postgres.git / summary / log / commit / refs

commit    6c426cd43790d56e6b96c21ae2d968ceb733bdde
Author:   Tom Lane <tgl@sss.pgh.pa.us>
Date:     Tue Mar 31 21:06:22 2020 +0000
First released in: 13.0, 12.3

    Fix race condition in statext_store().
    
    Must hold some lock on the pg_statistic_ext_data catalog *before*
    we look up the tuple we aim to replace.  Otherwise a concurrent
    VACUUM FULL or similar operation could move it to a different TID,
    leaving us trying to replace the wrong tuple.
    
    Back-patch to v12 where this got broken.
    
    Credit goes to Dean Rasheed; I'm just doing the clerical work.
    
    Discussion: https://postgr.es/m/CAEZATCU0zHMDiQV0g8P2U+YSP9C1idUPrn79DajsbonwkN0xvQ@mail.gmail.com


src/backend/statistics/extended_stats.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c index 4516c97f406..d8e51500232 100644 --- a/src/backend/statistics/extended_stats.c +++ b/src/backend/statistics/extended_stats.c @@ -322,12 +322,14 @@ statext_store(Oid statOid, MVNDistinct *ndistinct, MVDependencies *dependencies, MCVList *mcv, VacAttrStats **stats) { + Relation pg_stextdata; HeapTuple stup, oldtup; Datum values[Natts_pg_statistic_ext_data]; bool nulls[Natts_pg_statistic_ext_data]; bool replaces[Natts_pg_statistic_ext_data]; - Relation pg_stextdata; + + pg_stextdata = table_open(StatisticExtDataRelationId, RowExclusiveLock); memset(nulls, true, sizeof(nulls)); memset(replaces, false, sizeof(replaces)); @@ -371,8 +373,6 @@ statext_store(Oid statOid, elog(ERROR, "cache lookup failed for statistics object %u", statOid); /* replace it */ - pg_stextdata = table_open(StatisticExtDataRelationId, RowExclusiveLock); - stup = heap_modify_tuple(oldtup, RelationGetDescr(pg_stextdata), values, [parent: 1fd0eee66f1e]