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:
84
src/backend/utils/cache/inval.c
vendored
84
src/backend/utils/cache/inval.c
vendored
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user