Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2cc41ac

Browse files
committed
Fix hash index vs "snapshot too old" problemms
Hash indexes are not WAL-logged, and so do not maintain the LSN ofindex pages. Since the "snapshot too old" feature counts ondetecting error conditions using the LSN of a table and all indexeson it, this makes it impossible to safely do early vacuuming on anytable with a hash index, so add this to the tests for whether thexid used to vacuum a table can be adjusted based onold_snapshot_threshold.While at it, add a paragraph to the docs for old_snapshot_thresholdwhich specifically mentions this and other aspects of the featurewhich may otherwise surprise users.Problem reported and patch reviewed by Amit Kapila
1 parent9b66aa0 commit2cc41ac

File tree

6 files changed

+62
-6
lines changed

6 files changed

+62
-6
lines changed

‎doc/src/sgml/config.sgml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2077,6 +2077,19 @@ include_dir 'conf.d'
20772077
allowed, please note that in many workloads extreme bloat or
20782078
transaction ID wraparound may occur in much shorter time frames.
20792079
</para>
2080+
2081+
<para>
2082+
This setting does not attempt to guarantee that an error will be
2083+
generated under any particular circumstances. In fact, if the
2084+
correct results can be generated from (for example) a cursor which
2085+
has materialized a result set, no error will be generated even if the
2086+
underlying rows in the referenced table have been vacuumed away.
2087+
Some tables cannot safely be vacuumed early, and so will not be
2088+
affected by this setting. Examples include system catalogs and any
2089+
table which has a hash index. For such tables this setting will
2090+
neither reduce bloat nor create a possibility of a <literal>snapshot
2091+
too old</> error on scanning.
2092+
</para>
20802093
</listitem>
20812094
</varlistentry>
20822095
</variablelist>

‎src/backend/access/hash/hash.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,6 @@ hashgettuple(IndexScanDesc scan, ScanDirection dir)
279279
buf=so->hashso_curbuf;
280280
Assert(BufferIsValid(buf));
281281
page=BufferGetPage(buf);
282-
TestForOldSnapshot(scan->xs_snapshot,rel,page);
283282
maxoffnum=PageGetMaxOffsetNumber(page);
284283
for (offnum=ItemPointerGetOffsetNumber(current);
285284
offnum <=maxoffnum;

‎src/backend/access/hash/hashsearch.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,6 @@ _hash_first(IndexScanDesc scan, ScanDirection dir)
189189
/* Read the metapage */
190190
metabuf=_hash_getbuf(rel,HASH_METAPAGE,HASH_READ,LH_META_PAGE);
191191
page=BufferGetPage(metabuf);
192-
TestForOldSnapshot(scan->xs_snapshot,rel,page);
193192
metap=HashPageGetMeta(page);
194193

195194
/*
@@ -243,7 +242,6 @@ _hash_first(IndexScanDesc scan, ScanDirection dir)
243242
/* Fetch the primary bucket page for the bucket */
244243
buf=_hash_getbuf(rel,blkno,HASH_READ,LH_BUCKET_PAGE);
245244
page=BufferGetPage(buf);
246-
TestForOldSnapshot(scan->xs_snapshot,rel,page);
247245
opaque= (HashPageOpaque)PageGetSpecialPointer(page);
248246
Assert(opaque->hasho_bucket==bucket);
249247

@@ -350,7 +348,6 @@ _hash_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir)
350348
_hash_readnext(rel,&buf,&page,&opaque);
351349
if (BufferIsValid(buf))
352350
{
353-
TestForOldSnapshot(scan->xs_snapshot,rel,page);
354351
maxoff=PageGetMaxOffsetNumber(page);
355352
offnum=_hash_binsearch(page,so->hashso_sk_hash);
356353
}
@@ -392,7 +389,6 @@ _hash_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir)
392389
_hash_readprev(rel,&buf,&page,&opaque);
393390
if (BufferIsValid(buf))
394391
{
395-
TestForOldSnapshot(scan->xs_snapshot,rel,page);
396392
maxoff=PageGetMaxOffsetNumber(page);
397393
offnum=_hash_binsearch_last(page,so->hashso_sk_hash);
398394
}

‎src/backend/utils/cache/relcache.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5312,6 +5312,52 @@ RelationIdIsInInitFile(Oid relationId)
53125312
returnRelationSupportsSysCache(relationId);
53135313
}
53145314

5315+
/*
5316+
* Tells whether any index for the relation is unlogged.
5317+
*
5318+
* Any index using the hash AM is implicitly unlogged.
5319+
*
5320+
* Note: There doesn't seem to be any way to have an unlogged index attached
5321+
* to a permanent table except to create a hash index, but it seems best to
5322+
* keep this general so that it returns sensible results even when they seem
5323+
* obvious (like for an unlogged table) and to handle possible future unlogged
5324+
* indexes on permanent tables.
5325+
*/
5326+
bool
5327+
RelationHasUnloggedIndex(Relationrel)
5328+
{
5329+
List*indexoidlist;
5330+
ListCell*indexoidscan;
5331+
boolresult= false;
5332+
5333+
indexoidlist=RelationGetIndexList(rel);
5334+
5335+
foreach(indexoidscan,indexoidlist)
5336+
{
5337+
Oidindexoid=lfirst_oid(indexoidscan);
5338+
HeapTupletp;
5339+
Form_pg_classreltup;
5340+
5341+
tp=SearchSysCache1(RELOID,ObjectIdGetDatum(indexoid));
5342+
if (!HeapTupleIsValid(tp))
5343+
elog(ERROR,"cache lookup failed for relation %u",indexoid);
5344+
reltup= (Form_pg_class)GETSTRUCT(tp);
5345+
5346+
if (reltup->relpersistence==RELPERSISTENCE_UNLOGGED
5347+
||reltup->relam==HASH_AM_OID)
5348+
result= true;
5349+
5350+
ReleaseSysCache(tp);
5351+
5352+
if (result== true)
5353+
break;
5354+
}
5355+
5356+
list_free(indexoidlist);
5357+
5358+
returnresult;
5359+
}
5360+
53155361
/*
53165362
* Invalidate (remove) the init file during commit of a transaction that
53175363
* changed one or more of the relation cache entries that are kept in the

‎src/backend/utils/time/snapmgr.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1590,7 +1590,8 @@ TransactionIdLimitedForOldSnapshots(TransactionId recentXmin,
15901590
&&old_snapshot_threshold >=0
15911591
&&RelationNeedsWAL(relation)
15921592
&& !IsCatalogRelation(relation)
1593-
&& !RelationIsAccessibleInLogicalDecoding(relation))
1593+
&& !RelationIsAccessibleInLogicalDecoding(relation)
1594+
&& !RelationHasUnloggedIndex(relation))
15941595
{
15951596
int64ts=GetSnapshotCurrentTimestamp();
15961597
TransactionIdxlimit=recentXmin;

‎src/include/utils/rel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,5 +505,6 @@ typedef struct ViewOptions
505505
/* routines in utils/cache/relcache.c */
506506
externvoidRelationIncrementReferenceCount(Relationrel);
507507
externvoidRelationDecrementReferenceCount(Relationrel);
508+
externboolRelationHasUnloggedIndex(Relationrel);
508509

509510
#endif/* REL_H */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp