mirror of
https://github.com/postgres/postgres.git
synced 2025-07-07 00:36:50 +03:00
Fix hash index vs "snapshot too old" problemms
Hash indexes are not WAL-logged, and so do not maintain the LSN of index pages. Since the "snapshot too old" feature counts on detecting error conditions using the LSN of a table and all indexes on it, this makes it impossible to safely do early vacuuming on any table with a hash index, so add this to the tests for whether the xid used to vacuum a table can be adjusted based on old_snapshot_threshold. While at it, add a paragraph to the docs for old_snapshot_threshold which specifically mentions this and other aspects of the feature which may otherwise surprise users. Problem reported and patch reviewed by Amit Kapila
This commit is contained in:
46
src/backend/utils/cache/relcache.c
vendored
46
src/backend/utils/cache/relcache.c
vendored
@ -5312,6 +5312,52 @@ RelationIdIsInInitFile(Oid relationId)
|
||||
return RelationSupportsSysCache(relationId);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tells whether any index for the relation is unlogged.
|
||||
*
|
||||
* Any index using the hash AM is implicitly unlogged.
|
||||
*
|
||||
* Note: There doesn't seem to be any way to have an unlogged index attached
|
||||
* to a permanent table except to create a hash index, 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
|
||||
|| reltup->relam == HASH_AM_OID)
|
||||
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
|
||||
|
Reference in New Issue
Block a user