1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-23 14:01:44 +03:00

Fix relcache init file invalidation during Hot Standby for the case

where a database has a non-default tablespaceid. Pass thru MyDatabaseId
and MyDatabaseTableSpace to allow file path to be re-created in
standby and correct invalidation to take place in all cases.
Update and rework xact_commit_desc() debug messages.
Bug report from Tom by code inspection. Fix by me.
This commit is contained in:
Simon Riggs
2010-02-13 16:15:48 +00:00
parent a5acb7dfb9
commit dd428c79a4
4 changed files with 31 additions and 86 deletions

View File

@ -80,7 +80,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/cache/inval.c,v 1.95 2010/02/08 04:33:54 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/cache/inval.c,v 1.96 2010/02/13 16:15:47 sriggs Exp $
*
*-------------------------------------------------------------------------
*/
@ -861,15 +861,6 @@ xactGetCommittedInvalidationMessages(SharedInvalidationMessage **msgs,
* ProcessCommittedInvalidationMessages is executed by xact_redo_commit()
* to process invalidation messages added to commit records.
*
* If we have to invalidate the relcache init file we need to extract
* the database id from each message so we can correctly locate the database
* path and so remove that database's init file. We note that the relcache
* only contains entries for catalog tables from a single database, or
* shared relations. There are smgr invalidations that reference other
* databases but they never cause relcache file invalidations.
* So we only need to access either global or default tablespaces and
* never have need to scan pg_database to discover tablespace oids.
*
* Relcache init file invalidation requires processing both
* before and after we send the SI messages. See AtEOXact_Inval()
*
@ -879,79 +870,22 @@ xactGetCommittedInvalidationMessages(SharedInvalidationMessage **msgs,
*/
void
ProcessCommittedInvalidationMessages(SharedInvalidationMessage *msgs,
int nmsgs, bool RelcacheInitFileInval)
int nmsgs, bool RelcacheInitFileInval,
Oid dbid, Oid tsid)
{
Oid dboid = 0;
bool invalidate_global = false;
if (nmsgs > 0)
elog(trace_recovery(DEBUG4), "replaying commit with %d messages%s", nmsgs,
(RelcacheInitFileInval ? " and relcache file invalidation" : ""));
else
if (nmsgs <= 0)
return;
elog(trace_recovery(DEBUG4), "replaying commit with %d messages%s", nmsgs,
(RelcacheInitFileInval ? " and relcache file invalidation" : ""));
if (RelcacheInitFileInval)
{
int i;
/*
* Check messages to record dboid
*/
for (i = 0; i < nmsgs; i++)
{
SharedInvalidationMessage *inval_msg = &(msgs[i]);
Oid loop_dboid = 0;
/*
* Extract the database Oid from the message
*/
if (inval_msg->id >= 0)
loop_dboid = inval_msg->cc.dbId;
else if (inval_msg->id == SHAREDINVALRELCACHE_ID)
loop_dboid = inval_msg->rc.dbId;
else
{
/*
* Invalidation message is a catalog or nontransactional inval,
* which never cause relcache file invalidation,
* so we ignore them, no matter which db they're for.
*/
continue;
}
if (loop_dboid == 0)
invalidate_global = true;
else
{
Assert(dboid == 0 || dboid == loop_dboid);
dboid = loop_dboid;
}
}
/*
* If shared, dboid will be the global tablespace, otherwise it will
* be a local catalog relation in the default tablespace.
*/
if (invalidate_global)
RecoveryRelationCacheInitFileInvalidate(0, GLOBALTABLESPACE_OID, true);
if (dboid != 0)
RecoveryRelationCacheInitFileInvalidate(dboid, DEFAULTTABLESPACE_OID, true);
}
RecoveryRelationCacheInitFileInvalidate(dbid, tsid, true);
SendSharedInvalidMessages(msgs, nmsgs);
if (RelcacheInitFileInval)
{
/*
* Second invalidation, very similar to above. See RelationCacheInitFileInvalidate()
*/
if (invalidate_global)
RecoveryRelationCacheInitFileInvalidate(0, GLOBALTABLESPACE_OID, false);
if (dboid != 0)
RecoveryRelationCacheInitFileInvalidate(dboid, DEFAULTTABLESPACE_OID, false);
}
RecoveryRelationCacheInitFileInvalidate(dbid, tsid, false);
}
/*