mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-08 15:49:23 +02:00
Avoid catalog lookups in RelationAllowsEarlyPruning().
RelationAllowsEarlyPruning() performed a catalog scan, but is used
in two contexts where that was a bad idea:
1. In heap_page_prune_opt(), which runs very frequently in some large
scans. This caused major performance problems in a field report
that was easy to reproduce.
2. In TestForOldSnapshot(), which runs while we hold a buffer content
lock. It's not clear if this was guaranteed to be free of buffer
deadlock risk.
The check was introduced in commit 2cc41acd8
and defended against a
real problem: 9.6's hash indexes have no page LSN and so we can't
allow early pruning (ie the snapshot-too-old feature). We can remove
the check from all later releases though: hash indexes are now logged,
and there is no way to create UNLOGGED indexes on regular logged
tables.
If a future release allows such a combination, it might need to put
a similar check in place, but it'll need some more thought.
Back-patch to 10.
Author: Thomas Munro
Reviewed-by: Tom Lane, who spotted the second problem
Discussion: https://postgr.es/m/CA%2BhUKGKT8oTkp5jw_U4p0S-7UG9zsvtw_M47Y285bER6a2gD%2Bg%40mail.gmail.com
Discussion: https://postgr.es/m/CAA4eK1%2BWy%2BN4eE5zPm765h68LrkWc3Biu_8rzzi%2BOYX4j%2BiHRw%40mail.gmail.com
This commit is contained in:
parent
f51006ea96
commit
b9c4ccfefc
42
src/backend/utils/cache/relcache.c
vendored
42
src/backend/utils/cache/relcache.c
vendored
@ -6025,48 +6025,6 @@ RelationIdIsInInitFile(Oid relationId)
|
||||
return RelationSupportsSysCache(relationId);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tells whether any index for the relation is unlogged.
|
||||
*
|
||||
* Note: There doesn't seem to be any way to have an unlogged index attached
|
||||
* to a permanent table, but it seems best to keep this general so that it
|
||||
* returns sensible results even when they seem obvious (like for an unlogged
|
||||
* table) and to handle possible future unlogged indexes on permanent tables.
|
||||
*/
|
||||
bool
|
||||
RelationHasUnloggedIndex(Relation rel)
|
||||
{
|
||||
List *indexoidlist;
|
||||
ListCell *indexoidscan;
|
||||
bool result = false;
|
||||
|
||||
indexoidlist = RelationGetIndexList(rel);
|
||||
|
||||
foreach(indexoidscan, indexoidlist)
|
||||
{
|
||||
Oid indexoid = lfirst_oid(indexoidscan);
|
||||
HeapTuple tp;
|
||||
Form_pg_class reltup;
|
||||
|
||||
tp = SearchSysCache1(RELOID, ObjectIdGetDatum(indexoid));
|
||||
if (!HeapTupleIsValid(tp))
|
||||
elog(ERROR, "cache lookup failed for relation %u", indexoid);
|
||||
reltup = (Form_pg_class) GETSTRUCT(tp);
|
||||
|
||||
if (reltup->relpersistence == RELPERSISTENCE_UNLOGGED)
|
||||
result = true;
|
||||
|
||||
ReleaseSysCache(tp);
|
||||
|
||||
if (result == true)
|
||||
break;
|
||||
}
|
||||
|
||||
list_free(indexoidlist);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Invalidate (remove) the init file during commit of a transaction that
|
||||
* changed one or more of the relation cache entries that are kept in the
|
||||
|
@ -602,7 +602,6 @@ typedef struct ViewOptions
|
||||
/* routines in utils/cache/relcache.c */
|
||||
extern void RelationIncrementReferenceCount(Relation rel);
|
||||
extern void RelationDecrementReferenceCount(Relation rel);
|
||||
extern bool RelationHasUnloggedIndex(Relation rel);
|
||||
extern List *RelationGetRepsetList(Relation rel);
|
||||
|
||||
#endif /* REL_H */
|
||||
|
@ -40,7 +40,6 @@
|
||||
RelationNeedsWAL(rel) \
|
||||
&& !IsCatalogRelation(rel) \
|
||||
&& !RelationIsAccessibleInLogicalDecoding(rel) \
|
||||
&& !RelationHasUnloggedIndex(rel) \
|
||||
)
|
||||
|
||||
#define EarlyPruningEnabled(rel) (old_snapshot_threshold >= 0 && RelationAllowsEarlyPruning(rel))
|
||||
|
Loading…
Reference in New Issue
Block a user