postgres.git / summary / log / commit / refs

commit    a0a0c0c20ec5f8787bb1be5f476c4e59f6810634
Author:   Álvaro Herrera <alvherre@kurilemu.de>
Date:     Tue May 05 14:20:26 2026 +0000

    Skip other sessions' temp tables in REPACK, CLUSTER, and VACUUM FULL
    
    get_tables_to_repack() and get_all_vacuum_rels() were including other
    sessions' temporary tables in their output work list, causing REPACK,
    CLUSTER and VACUUM FULL (when executed without a table list) to attempt
    to acquire AccessExclusiveLock on them, potentially blocking for an
    extended time.  Fix by skipping other-session temp tables early, before
    they are added to the list.
    
    This issue is ancient, but there have been no complaints about it that I
    know of, so I'm opting for not backpatching at present.
    
    Author: Jim Jones <jim.jones@uni-muenster.de>
    Reviewed-by: Chao Li <li.evan.chao@gmail.com>
    Reviewed-by: Zsolt Parragi <zsolt.parragi@percona.com>
    Discussion: https://postgr.es/m/0b555318-2bf2-46df-9377-09629a2a59db@uni-muenster.de


src/backend/commands/repack.c | 25 ++++++++++++++++++++++++- src/backend/commands/vacuum.c | 5 +++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index dca3997c31b..9a199dd9bfb 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -2106,6 +2106,8 @@ get_tables_to_repack(RepackCommand cmd, bool usingindex, MemoryContext permcxt) { RelToCluster *rtc; Form_pg_index index; + HeapTuple classtup; + Form_pg_class classForm; MemoryContext oldcxt; index = (Form_pg_index) GETSTRUCT(tuple); @@ -2120,11 +2122,24 @@ get_tables_to_repack(RepackCommand cmd, bool usingindex, MemoryContext permcxt) continue; /* Verify that the table still exists; skip if not */ - if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(index->indrelid))) + classtup = SearchSysCache1(RELOID, ObjectIdGetDatum(index->indrelid)); + if (!HeapTupleIsValid(classtup)) { UnlockRelationOid(index->indrelid, AccessShareLock); continue; } + classForm = (Form_pg_class) GETSTRUCT(classtup); + + /* Skip temp relations belonging to other sessions */ + if (classForm->relpersistence == RELPERSISTENCE_TEMP && + !isTempOrTempToastNamespace(classForm->relnamespace)) + { + ReleaseSysCache(classtup); + UnlockRelationOid(index->indrelid, AccessShareLock); + continue; + } + + ReleaseSysCache(classtup); /* noisily skip rels which the user can't process */ if (!repack_is_permitted_for_relation(cmd, index->indrelid, @@ -2180,6 +2195,14 @@ get_tables_to_repack(RepackCommand cmd, bool usingindex, MemoryContext permcxt) continue; } + /* Skip temp relations belonging to other sessions */ + if (class->relpersistence == RELPERSISTENCE_TEMP && + !isTempOrTempToastNamespace(class->relnamespace)) + { + UnlockRelationOid(class->oid, AccessShareLock); + continue; + } + /* noisily skip rels which the user can't process */ if (!repack_is_permitted_for_relation(cmd, class->oid, GetUserId())) diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 99d0db82ed7..a4abb29cf64 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -1063,6 +1063,11 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) classForm->relkind != RELKIND_PARTITIONED_TABLE) continue; + /* Skip temp relations belonging to other sessions */ + if (classForm->relpersistence == RELPERSISTENCE_TEMP && + !isTempOrTempToastNamespace(classForm->relnamespace)) + continue; + /* check permissions of relation */ if (!vacuum_is_permitted_for_relation(relid, classForm, options)) continue; [parent: 676626426285]