agora inbox for pgsql-hackers@postgresql.orghelp / color / mirror / Atom feed
[PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. 1520+ messages / 1 participants [nested] [flat]
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 7c958b06273..f146e14d3d6 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8a5c9818ed6..9f5f8e692b8 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1053,6 +1053,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1062,6 +1064,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2186,6 +2190,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2195,6 +2201,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 3e95d4cfd16..2921148ceba 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.50.1 (Apple Git-155) --qmnHGfI3v6dYD6Bi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v4-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 10 ++++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 120bac8875f..b89278ef032 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 9d5f130af7e..63eb2548da1 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1118,6 +1118,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1127,6 +1129,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -1225,6 +1229,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) MultiXactState->offsetStopLimit - nextOffset + nmembers, MultiXactState->oldestMultiXactDB, MultiXactState->offsetStopLimit - nextOffset + nmembers), + errdetail("Approximately %.2f%% of multixact members are available for use.", + (double) (MultiXactState->offsetStopLimit - nextOffset + nmembers) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database with reduced \"vacuum_multixact_freeze_min_age\" and \"vacuum_multixact_freeze_table_age\" settings."))); ExtendMultiXactMember(nextOffset, nmembers); @@ -2414,6 +2420,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2423,6 +2431,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --i7+bPtDlPvAbCgMY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v1-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..257c6a5435d 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transaction IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index f4fab7edfee..39e5b691573 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1017,6 +1017,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1026,6 +1028,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / (MaxMultiXactId / 2) * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2134,6 +2138,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2143,6 +2149,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / (MaxMultiXactId / 2) * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..32961b9acab 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / (MaxTransactionId / 2) * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --hUJBJnA49L/nki7N Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v3-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
* [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. @ 2025-11-14 15:59 Nathan Bossart <nathan@postgresql.org> 0 siblings, 0 replies; 1520+ messages in thread From: Nathan Bossart @ 2025-11-14 15:59 UTC (permalink / raw) --- doc/src/sgml/maintenance.sgml | 1 + src/backend/access/transam/multixact.c | 8 ++++++++ src/backend/access/transam/varsup.c | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 08e6489afb8..c8ba94303f1 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -674,6 +674,7 @@ SELECT datname, age(datfrozenxid) FROM pg_database; <programlisting> WARNING: database "mydb" must be vacuumed within 39985967 transactions +DETAIL: Approximately 1.86% of transactions IDs are available for use. HINT: To avoid XID assignment failures, execute a database-wide VACUUM in that database. </programlisting> diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 8ba2f4529dc..e1ac4bf4c0b 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1040,6 +1040,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datname, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -1049,6 +1051,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) multiWrapLimit - result, oldest_datoid, multiWrapLimit - result), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - result) / PG_INT32_MAX * 100), errhint("Execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -2166,6 +2170,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datname, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -2175,6 +2181,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid) multiWrapLimit - curMulti, oldest_datoid, multiWrapLimit - curMulti), + errdetail("Approximately %.2f%% of MultiXactIds are available for use.", + (double) (multiWrapLimit - curMulti) / PG_INT32_MAX * 100), errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index f8c4dada7c9..962396bae10 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -175,6 +175,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid transaction ID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -182,6 +184,8 @@ GetNewTransactionId(bool isSubXact) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - xid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - xid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } @@ -490,6 +494,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database \"%s\" must be vacuumed within %u transactions", oldest_datname, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); else @@ -497,6 +503,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) (errmsg("database with OID %u must be vacuumed within %u transactions", oldest_datoid, xidWrapLimit - curXid), + errdetail("Approximately %.2f%% of transaction IDs are available for use.", + (double) (xidWrapLimit - curXid) / PG_INT32_MAX * 100), errhint("To avoid XID assignment failures, execute a database-wide VACUUM in that database.\n" "You might also need to commit or roll back old prepared transactions, or drop stale replication slots."))); } -- 2.39.5 (Apple Git-154) --ChIdkGVrtcKYZbRk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v2-0002-Bump-transaction-ID-limit-to-warn-at-100M.patch ^ permalink raw reply [nested|flat] 1520+ messages in thread
end of thread, other threads:[~2025-11-14 15:59 UTC | newest] Thread overview: 1520+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v1 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v2 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v4 1/2] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org> 2025-11-14 15:59 [PATCH v3 1/3] Add percentage of transaction IDs that are available to wraparound warnings. Nathan Bossart <nathan@postgresql.org>
This inbox is served by agora; see mirroring instructions for how to clone and mirror all data and code used for this inbox