diff options
author | Kevin Grittner <kgrittn@postgresql.org> | 2016-05-06 07:47:12 -0500 |
---|---|---|
committer | Kevin Grittner <kgrittn@postgresql.org> | 2016-05-06 07:47:12 -0500 |
commit | 2cc41acd8fa3ebb8f0501c6102a253fb7053cf46 (patch) | |
tree | da067fb39fbe366b6f15746173050582e2b8f56c /src/backend/utils/cache | |
parent | 9b66aa006f81b2705337ca223daeeabf4db6453a (diff) | |
download | postgresql-2cc41acd8fa3ebb8f0501c6102a253fb7053cf46.tar.gz postgresql-2cc41acd8fa3ebb8f0501c6102a253fb7053cf46.zip |
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
Diffstat (limited to 'src/backend/utils/cache')
-rw-r--r-- | src/backend/utils/cache/relcache.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 432feefa609..79cc3df590a 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -5313,6 +5313,52 @@ RelationIdIsInInitFile(Oid 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 * local init file. |