aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/dbcommands.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2005-03-12 21:33:55 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2005-03-12 21:33:55 +0000
commit78a572bf0c7ba7ec3a4558fd88870f8fdff30dac (patch)
tree228b3da4437922b0feb614127157d05579a9c051 /src/backend/commands/dbcommands.c
parentc7bbe99452c20d76da58a12b529164719bf798b8 (diff)
downloadpostgresql-78a572bf0c7ba7ec3a4558fd88870f8fdff30dac.tar.gz
postgresql-78a572bf0c7ba7ec3a4558fd88870f8fdff30dac.zip
When cloning template0 (or other fully-frozen databases), set the new
database's datallowconn and datfrozenxid to the current transaction ID instead of copying the source database's values. This is OK because we assume the source DB contains no normal transaction IDs whatsoever. This keeps VACUUM from immediately starting to complain about unvacuumed databases in the situation where we are more than 2 billion transactions out from the XID stamp of template0. Per discussion with Milen Radev (although his complaint turned out to be due to something else, but the problem is real anyway).
Diffstat (limited to 'src/backend/commands/dbcommands.c')
-rw-r--r--src/backend/commands/dbcommands.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index a076ff4c9cd..f3327b1fb2f 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.153 2005/03/12 21:11:50 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.154 2005/03/12 21:33:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -54,7 +54,8 @@
/* non-export function prototypes */
static bool get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
- int *encodingP, bool *dbIsTemplateP, Oid *dbLastSysOidP,
+ int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
+ Oid *dbLastSysOidP,
TransactionId *dbVacuumXidP, TransactionId *dbFrozenXidP,
Oid *dbTablespace);
static bool have_createdb_privilege(void);
@@ -73,6 +74,7 @@ createdb(const CreatedbStmt *stmt)
AclId src_owner;
int src_encoding;
bool src_istemplate;
+ bool src_allowconn;
Oid src_lastsysoid;
TransactionId src_vacuumxid;
TransactionId src_frozenxid;
@@ -217,7 +219,8 @@ createdb(const CreatedbStmt *stmt)
* idea, so accept possibility of race to create. We will check again
* after we grab the exclusive lock.
*/
- if (get_db_info(dbname, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL))
+ if (get_db_info(dbname, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_DATABASE),
errmsg("database \"%s\" already exists", dbname)));
@@ -229,7 +232,7 @@ createdb(const CreatedbStmt *stmt)
dbtemplate = "template1"; /* Default template database name */
if (!get_db_info(dbtemplate, &src_dboid, &src_owner, &src_encoding,
- &src_istemplate, &src_lastsysoid,
+ &src_istemplate, &src_allowconn, &src_lastsysoid,
&src_vacuumxid, &src_frozenxid, &src_deftablespace))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_DATABASE),
@@ -329,6 +332,16 @@ createdb(const CreatedbStmt *stmt)
}
/*
+ * Normally we mark the new database with the same datvacuumxid and
+ * datfrozenxid as the source. However, if the source is not allowing
+ * connections then we assume it is fully frozen, and we can set the
+ * current transaction ID as the xid limits. This avoids immediately
+ * starting to generate warnings after cloning template0.
+ */
+ if (!src_allowconn)
+ src_vacuumxid = src_frozenxid = GetCurrentTransactionId();
+
+ /*
* Preassign OID for pg_database tuple, so that we can compute db
* path.
*/
@@ -455,7 +468,8 @@ createdb(const CreatedbStmt *stmt)
pg_database_rel = heap_openr(DatabaseRelationName, ExclusiveLock);
/* Check to see if someone else created same DB name meanwhile. */
- if (get_db_info(dbname, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL))
+ if (get_db_info(dbname, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL))
{
/* Don't hold lock while doing recursive remove */
heap_close(pg_database_rel, ExclusiveLock);
@@ -552,7 +566,7 @@ dropdb(const char *dbname)
pgdbrel = heap_openr(DatabaseRelationName, ExclusiveLock);
if (!get_db_info(dbname, &db_id, &db_owner, NULL,
- &db_istemplate, NULL, NULL, NULL, NULL))
+ &db_istemplate, NULL, NULL, NULL, NULL, NULL))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("database \"%s\" does not exist", dbname)));
@@ -936,7 +950,8 @@ AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId)
static bool
get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
- int *encodingP, bool *dbIsTemplateP, Oid *dbLastSysOidP,
+ int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
+ Oid *dbLastSysOidP,
TransactionId *dbVacuumXidP, TransactionId *dbFrozenXidP,
Oid *dbTablespace)
{
@@ -978,6 +993,9 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
/* allowed as template? */
if (dbIsTemplateP)
*dbIsTemplateP = dbform->datistemplate;
+ /* allowing connections? */
+ if (dbAllowConnP)
+ *dbAllowConnP = dbform->datallowconn;
/* last system OID used in database */
if (dbLastSysOidP)
*dbLastSysOidP = dbform->datlastsysoid;