mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-05 19:09:58 +08: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:
parent
a5acb7dfb9
commit
dd428c79a4
@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.284 2010/02/08 04:33:53 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.285 2010/02/13 16:15:46 sriggs Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -951,6 +951,9 @@ RecordTransactionCommit(void)
|
||||
if (forceSyncCommit)
|
||||
xlrec.xinfo |= XACT_COMPLETION_FORCE_SYNC_COMMIT;
|
||||
|
||||
xlrec.dbId = MyDatabaseId;
|
||||
xlrec.tsId = MyDatabaseTableSpace;
|
||||
|
||||
/*
|
||||
* Mark ourselves as within our "commit critical section". This
|
||||
* forces any concurrent checkpoint to wait until we've updated
|
||||
@ -4412,7 +4415,8 @@ xact_redo_commit(xl_xact_commit *xlrec, TransactionId xid, XLogRecPtr lsn)
|
||||
* as occurs in .
|
||||
*/
|
||||
ProcessCommittedInvalidationMessages(inval_msgs, xlrec->nmsgs,
|
||||
XactCompletionRelcacheInitFileInval(xlrec));
|
||||
XactCompletionRelcacheInitFileInval(xlrec),
|
||||
xlrec->dbId, xlrec->tsId);
|
||||
|
||||
/*
|
||||
* Release locks, if any. We do this for both two phase and normal
|
||||
@ -4596,15 +4600,11 @@ xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
|
||||
{
|
||||
int i;
|
||||
TransactionId *xacts;
|
||||
SharedInvalidationMessage *msgs;
|
||||
|
||||
xacts = (TransactionId *) &xlrec->xnodes[xlrec->nrels];
|
||||
msgs = (SharedInvalidationMessage *) &xacts[xlrec->nsubxacts];
|
||||
|
||||
if (XactCompletionRelcacheInitFileInval(xlrec))
|
||||
appendStringInfo(buf, "; relcache init file inval");
|
||||
|
||||
appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
|
||||
|
||||
if (xlrec->nrels > 0)
|
||||
{
|
||||
appendStringInfo(buf, "; rels:");
|
||||
@ -4624,6 +4624,14 @@ xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
|
||||
}
|
||||
if (xlrec->nmsgs > 0)
|
||||
{
|
||||
SharedInvalidationMessage *msgs;
|
||||
|
||||
msgs = (SharedInvalidationMessage *) &xacts[xlrec->nsubxacts];
|
||||
|
||||
if (XactCompletionRelcacheInitFileInval(xlrec))
|
||||
appendStringInfo(buf, "; relcache init file inval dbid %u tsid %u",
|
||||
xlrec->dbId, xlrec->tsId);
|
||||
|
||||
appendStringInfo(buf, "; inval msgs:");
|
||||
for (i = 0; i < xlrec->nmsgs; i++)
|
||||
{
|
||||
|
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/access/xact.h,v 1.101 2010/02/08 04:33:54 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/access/xact.h,v 1.102 2010/02/13 16:15:47 sriggs Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -102,6 +102,8 @@ typedef struct xl_xact_commit
|
||||
int nrels; /* number of RelFileNodes */
|
||||
int nsubxacts; /* number of subtransaction XIDs */
|
||||
int nmsgs; /* number of shared inval msgs */
|
||||
Oid dbId; /* MyDatabaseId */
|
||||
Oid tsId; /* MyDatabaseTableSpace */
|
||||
/* Array of RelFileNode(s) to drop at commit */
|
||||
RelFileNode xnodes[1]; /* VARIABLE LENGTH ARRAY */
|
||||
/* ARRAY OF COMMITTED SUBTRANSACTION XIDs FOLLOWS */
|
||||
@ -119,7 +121,7 @@ typedef struct xl_xact_commit
|
||||
* transaction completion.
|
||||
*/
|
||||
#define XACT_COMPLETION_UPDATE_RELCACHE_FILE 0x01
|
||||
#define XACT_COMPLETION_FORCE_SYNC_COMMIT 0x04
|
||||
#define XACT_COMPLETION_FORCE_SYNC_COMMIT 0x02
|
||||
|
||||
/* Access macros for above flags */
|
||||
#define XactCompletionRelcacheInitFileInval(xlrec) ((xlrec)->xinfo & XACT_COMPLETION_UPDATE_RELCACHE_FILE)
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/storage/sinval.h,v 1.57 2010/02/07 20:48:13 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/storage/sinval.h,v 1.58 2010/02/13 16:15:48 sriggs Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -134,6 +134,7 @@ extern bool DisableCatchupInterrupt(void);
|
||||
extern int xactGetCommittedInvalidationMessages(SharedInvalidationMessage **msgs,
|
||||
bool *RelcacheInitFileInval);
|
||||
extern void ProcessCommittedInvalidationMessages(SharedInvalidationMessage *msgs,
|
||||
int nmsgs, bool RelcacheInitFileInval);
|
||||
int nmsgs, bool RelcacheInitFileInval,
|
||||
Oid dbid, Oid tsid);
|
||||
|
||||
#endif /* SINVAL_H */
|
||||
|
Loading…
Reference in New Issue
Block a user