1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-15 19:21:59 +03:00

Change the default value of max_prepared_transactions to zero, and add

documentation warnings against setting it nonzero unless active use of
prepared transactions is intended and a suitable transaction manager has been
installed.  This should help to prevent the type of scenario we've seen
several times now where a prepared transaction is forgotten and eventually
causes severe maintenance problems (or even anti-wraparound shutdown).

The only real reason we had the default be nonzero in the first place was to
support regression testing of the feature.  To still be able to do that,
tweak pg_regress to force a nonzero value during "make check".  Since we
cannot force a nonzero value in "make installcheck", add a variant regression
test "expected" file that shows the results that will be obtained when
max_prepared_transactions is zero.

Also, extend the HINT messages for transaction wraparound warnings to mention
the possibility that old prepared transactions are causing the problem.

All per today's discussion.
This commit is contained in:
Tom Lane
2009-04-23 00:23:46 +00:00
parent bae8102f52
commit 8d4f2ecd41
10 changed files with 304 additions and 52 deletions

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.51 2009/01/01 17:23:36 momjian Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.52 2009/04/23 00:23:45 tgl Exp $
*
* NOTES
* Each global transaction is associated with a global transaction
@ -68,7 +68,7 @@
#define TWOPHASE_DIR "pg_twophase"
/* GUC variable, can't be changed after startup */
int max_prepared_xacts = 5;
int max_prepared_xacts = 0;
/*
* This struct describes one global transaction that is in prepared state
@ -228,6 +228,13 @@ MarkAsPreparing(TransactionId xid, const char *gid,
errmsg("transaction identifier \"%s\" is too long",
gid)));
/* fail immediately if feature is disabled */
if (max_prepared_xacts == 0)
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("prepared transactions are disabled"),
errhint("Set max_prepared_transactions to a nonzero value.")));
LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
/*

View File

@ -6,7 +6,7 @@
* Copyright (c) 2000-2009, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/transam/varsup.c,v 1.83 2009/01/01 17:23:36 momjian Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/varsup.c,v 1.84 2009/04/23 00:23:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -86,14 +86,16 @@ GetNewTransactionId(bool isSubXact)
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("database is not accepting commands to avoid wraparound data loss in database \"%s\"",
NameStr(ShmemVariableCache->limit_datname)),
errhint("Stop the postmaster and use a standalone backend to vacuum database \"%s\".",
errhint("Stop the postmaster and use a standalone backend to vacuum database \"%s\".\n"
"You might also need to commit or roll back old prepared transactions.",
NameStr(ShmemVariableCache->limit_datname))));
else if (TransactionIdFollowsOrEquals(xid, ShmemVariableCache->xidWarnLimit))
ereport(WARNING,
(errmsg("database \"%s\" must be vacuumed within %u transactions",
NameStr(ShmemVariableCache->limit_datname),
ShmemVariableCache->xidWrapLimit - xid),
errhint("To avoid a database shutdown, execute a database-wide VACUUM in \"%s\".",
errhint("To avoid a database shutdown, execute a database-wide VACUUM in \"%s\".\n"
"You might also need to commit or roll back old prepared transactions.",
NameStr(ShmemVariableCache->limit_datname))));
}
@ -299,7 +301,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid,
(errmsg("database \"%s\" must be vacuumed within %u transactions",
NameStr(*oldest_datname),
xidWrapLimit - curXid),
errhint("To avoid a database shutdown, execute a database-wide VACUUM in \"%s\".",
errhint("To avoid a database shutdown, execute a database-wide VACUUM in \"%s\".\n"
"You might also need to commit or roll back old prepared transactions.",
NameStr(*oldest_datname))));
}