mirror of
https://github.com/postgres/postgres.git
synced 2025-05-06 19:59:18 +03: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
80d0e5ba3f
commit
720b59b55b
42
src/backend/utils/cache/relcache.c
vendored
42
src/backend/utils/cache/relcache.c
vendored
@ -5913,48 +5913,6 @@ RelationIdIsInInitFile(Oid relationId)
|
|||||||
return RelationSupportsSysCache(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
|
* 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
|
* changed one or more of the relation cache entries that are kept in the
|
||||||
|
@ -605,6 +605,5 @@ typedef struct ViewOptions
|
|||||||
/* routines in utils/cache/relcache.c */
|
/* routines in utils/cache/relcache.c */
|
||||||
extern void RelationIncrementReferenceCount(Relation rel);
|
extern void RelationIncrementReferenceCount(Relation rel);
|
||||||
extern void RelationDecrementReferenceCount(Relation rel);
|
extern void RelationDecrementReferenceCount(Relation rel);
|
||||||
extern bool RelationHasUnloggedIndex(Relation rel);
|
|
||||||
|
|
||||||
#endif /* REL_H */
|
#endif /* REL_H */
|
||||||
|
@ -40,7 +40,6 @@
|
|||||||
RelationNeedsWAL(rel) \
|
RelationNeedsWAL(rel) \
|
||||||
&& !IsCatalogRelation(rel) \
|
&& !IsCatalogRelation(rel) \
|
||||||
&& !RelationIsAccessibleInLogicalDecoding(rel) \
|
&& !RelationIsAccessibleInLogicalDecoding(rel) \
|
||||||
&& !RelationHasUnloggedIndex(rel) \
|
|
||||||
)
|
)
|
||||||
|
|
||||||
#define EarlyPruningEnabled(rel) (old_snapshot_threshold >= 0 && RelationAllowsEarlyPruning(rel))
|
#define EarlyPruningEnabled(rel) (old_snapshot_threshold >= 0 && RelationAllowsEarlyPruning(rel))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user