diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2024-01-31 12:31:02 +0200 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2024-01-31 12:31:02 +0200 |
commit | 21d9c3ee4ef74e2229341d39811c97f85071c90a (patch) | |
tree | 5400cf27276fae4ffa9566f107bb27f084da119c /src/backend/access/transam/xlogutils.c | |
parent | 6a8ffe812d194ba6f4f26791b6388a4837d17d6c (diff) | |
download | postgresql-21d9c3ee4ef74e2229341d39811c97f85071c90a.tar.gz postgresql-21d9c3ee4ef74e2229341d39811c97f85071c90a.zip |
Give SMgrRelation pointers a well-defined lifetime.
After calling smgropen(), it was not clear how long you could continue
to use the result, because various code paths including cache
invalidation could call smgrclose(), which freed the memory.
Guarantee that the object won't be destroyed until the end of the
current transaction, or in recovery, the commit/abort record that
destroys the underlying storage.
smgrclose() is now just an alias for smgrrelease(). It closes files
and forgets all state except the rlocator, but keeps the SMgrRelation
object valid.
A new smgrdestroy() function is used by rare places that know there
should be no other references to the SMgrRelation.
The short version:
* smgrclose() is now just an alias for smgrrelease(). It releases
resources, but doesn't destroy until EOX
* smgrdestroy() now frees memory, and should rarely be used.
Existing code should be unaffected, but it is now possible for code that
has an SMgrRelation object to use it repeatedly during a transaction as
long as the storage hasn't been physically dropped. Such code would
normally hold a lock on the relation.
This also replaces the "ownership" mechanism of SMgrRelations with a
pin counter. An SMgrRelation can now be "pinned", which prevents it
from being destroyed at end of transaction. There can be multiple pins
on the same SMgrRelation. In practice, the pin mechanism is only used
by the relcache, so there cannot be more than one pin on the same
SMgrRelation. Except with swap_relation_files XXX
Author: Thomas Munro, Heikki Linnakangas
Reviewed-by: Robert Haas <robertmhaas@gmail.com>
Discussion: https://www.postgresql.org/message-id/CA%2BhUKGJ8NTvqLHz6dqbQnt2c8XCki4r2QvXjBQcXpVwxTY_pvA@mail.gmail.com
Diffstat (limited to 'src/backend/access/transam/xlogutils.c')
-rw-r--r-- | src/backend/access/transam/xlogutils.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/src/backend/access/transam/xlogutils.c b/src/backend/access/transam/xlogutils.c index aa8667abd10..945f1f790d5 100644 --- a/src/backend/access/transam/xlogutils.c +++ b/src/backend/access/transam/xlogutils.c @@ -616,7 +616,11 @@ CreateFakeRelcacheEntry(RelFileLocator rlocator) rel->rd_lockInfo.lockRelId.dbId = rlocator.dbOid; rel->rd_lockInfo.lockRelId.relId = rlocator.relNumber; - rel->rd_smgr = NULL; + /* + * Set up a non-pinned SMgrRelation reference, so that we don't need to + * worry about unpinning it on error. + */ + rel->rd_smgr = smgropen(rlocator, InvalidBackendId); return rel; } @@ -627,9 +631,6 @@ CreateFakeRelcacheEntry(RelFileLocator rlocator) void FreeFakeRelcacheEntry(Relation fakerel) { - /* make sure the fakerel is not referenced by the SmgrRelation anymore */ - if (fakerel->rd_smgr != NULL) - smgrclearowner(&fakerel->rd_smgr, fakerel->rd_smgr); pfree(fakerel); } @@ -656,10 +657,10 @@ XLogDropDatabase(Oid dbid) /* * This is unnecessarily heavy-handed, as it will close SMgrRelation * objects for other databases as well. DROP DATABASE occurs seldom enough - * that it's not worth introducing a variant of smgrclose for just this - * purpose. XXX: Or should we rather leave the smgr entries dangling? + * that it's not worth introducing a variant of smgrdestroy for just this + * purpose. */ - smgrcloseall(); + smgrdestroyall(); forget_invalid_pages_db(dbid); } |