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]