On Fri, Jan 10, 2020 at 08:07:48PM +0900, Michael Paquier wrote: > Thinking more about it, this has a race condition if a temporary > schema is removed after collecting the OIDs in the drop phase. So the > updated attached is actually much more conservative and does not need > an update of the log message, without giving up on the improvements > done in v11~. In 9.4~10, the code of the second phase relies on > GetTempNamespaceBackendId() which causes an orphaned relation to not > be dropped in the event of a missing namespace. I'll just leave that > alone for a couple of days now..
And back on that one, I still like better the solution as of the attached which skips any relations with their namespace gone missing as 246a6c87's intention was only to allow orphaned temp relations to be dropped by autovacuum when a backend slot is connected, but not using yet its own temp namespace. If we want the drop of temp relations to work properly, more thoughts are needed regarding the storage part, and I am not actually sure that it is autovacuum's job to handle that better. Any thoughts? -- Michael
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index f0e40e36af..9eb8132a37 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -2071,9 +2071,11 @@ do_autovacuum(void) { /* * We just ignore it if the owning backend is still active and - * using the temporary schema. + * using the temporary schema. If the namespace does not exist + * ignore the entry. */ - if (!isTempNamespaceInUse(classForm->relnamespace)) + if (!isTempNamespaceInUse(classForm->relnamespace) && + get_namespace_name(classForm->relnamespace) != NULL) { /* * The table seems to be orphaned -- although it might be that @@ -2202,6 +2204,7 @@ do_autovacuum(void) Oid relid = lfirst_oid(cell); Form_pg_class classForm; ObjectAddress object; + char *nspname; /* * Check for user-requested abort. @@ -2243,7 +2246,15 @@ do_autovacuum(void) continue; } - if (isTempNamespaceInUse(classForm->relnamespace)) + nspname = get_namespace_name(classForm->relnamespace); + + /* + * Nothing to do for a relation with a missing namespace. This + * check is the same as above when building the list of orphan + * relations. + */ + if (isTempNamespaceInUse(classForm->relnamespace) || + nspname == NULL) { UnlockRelationOid(relid, AccessExclusiveLock); continue; @@ -2253,8 +2264,7 @@ do_autovacuum(void) ereport(LOG, (errmsg("autovacuum: dropping orphan temp table \"%s.%s.%s\"", get_database_name(MyDatabaseId), - get_namespace_name(classForm->relnamespace), - NameStr(classForm->relname)))); + nspname, NameStr(classForm->relname)))); object.classId = RelationRelationId; object.objectId = relid;
signature.asc
Description: PGP signature