diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2014-05-14 14:55:48 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2014-05-14 14:56:08 -0400 |
commit | b23b0f5588d2e2f15edff66e072e339a8c9616a7 (patch) | |
tree | 4f4fc7804d31955fd244a899867e14ee2ebea922 /src/backend/access/heap/heapam.c | |
parent | ac53295d667e7727d7b70ddf11d82c067870501f (diff) | |
download | postgresql-b23b0f5588d2e2f15edff66e072e339a8c9616a7.tar.gz postgresql-b23b0f5588d2e2f15edff66e072e339a8c9616a7.zip |
Code review for recent changes in relcache.c.
rd_replidindex should be managed the same as rd_oidindex, and rd_keyattr
and rd_idattr should be managed like rd_indexattr. Omissions in this area
meant that the bitmapsets computed for rd_keyattr and rd_idattr would be
leaked during any relcache flush, resulting in a slow but permanent leak in
CacheMemoryContext. There was also a tiny probability of relcache entry
corruption if we ran out of memory at just the wrong point in
RelationGetIndexAttrBitmap. Otherwise, the fields were not zeroed where
expected, which would not bother the code any AFAICS but could greatly
confuse anyone examining the relcache entry while debugging.
Also, create an API function RelationGetReplicaIndex rather than letting
non-relcache code be intimate with the mechanisms underlying caching of
that value (we won't even mention the memory leak there).
Also, fix a relcache flush hazard identified by Andres Freund:
RelationGetIndexAttrBitmap must not assume that rd_replidindex stays valid
across index_open.
The aspects of this involving rd_keyattr date back to 9.3, so back-patch
those changes.
Diffstat (limited to 'src/backend/access/heap/heapam.c')
-rw-r--r-- | src/backend/access/heap/heapam.c | 13 |
1 files changed, 6 insertions, 7 deletions
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 405117a5261..b77c32c6ab6 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -7113,6 +7113,7 @@ static HeapTuple ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_changed, bool *copy) { TupleDesc desc = RelationGetDescr(relation); + Oid replidindex; Relation idx_rel; TupleDesc idx_desc; char replident = relation->rd_rel->relreplident; @@ -7147,18 +7148,16 @@ ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_changed, bool * if (!key_changed) return NULL; - /* needs to already have been fetched? */ - if (relation->rd_indexvalid == 0) - RelationGetIndexList(relation); - - if (!OidIsValid(relation->rd_replidindex)) + /* find the replica identity index */ + replidindex = RelationGetReplicaIndex(relation); + if (!OidIsValid(replidindex)) { - elog(DEBUG4, "Could not find configured replica identity for table \"%s\"", + elog(DEBUG4, "could not find configured replica identity for table \"%s\"", RelationGetRelationName(relation)); return NULL; } - idx_rel = RelationIdGetRelation(relation->rd_replidindex); + idx_rel = RelationIdGetRelation(replidindex); idx_desc = RelationGetDescr(idx_rel); /* deform tuple, so we have fast access to columns */ |