postgres.git / summary / log / commit / refs

commit    b7258a30aa6f1d4b53491174f372df07c5a6cd97
Author:   Alvaro Herrera <alvherre@alvh.no-ip.org>
Date:     Thu Dec 27 19:17:40 2018 +0000
First released in: 9.4.21, 9.5.16, 9.6.12, 10.7

    Have DISCARD ALL/TEMP remove leftover temp tables
    
    Previously, it would only remove temp tables created in the same
    session; but if the session uses the BackendId of a previously crashed
    backend that left temp tables around, those would not get removed.
    Since autovacuum would not drop them either (because it sees that the
    BackendId is in use by the current session) these can cause annoying
    xid-wraparound warnings.
    
    Apply to branches 9.4 to 10.  This is not a problem since version 11,
    because commit 943576bddcb5 added state tracking that makes autovacuum
    realize that those temp tables are not ours, so it removes them.
    
    This is useful to handle in DISCARD, because even though it does not
    handle all situations, it does handle the common one where a connection
    pooler keeps the same session open for an indefinitely long time.
    
    Discussion: https://postgr.es/m/20181226190834.wsk2wzott5yzrjiq@alvherre.pgsql
    Reviewed-by: Takayuki Tsunakawa, Michaƫl Paquier


src/backend/catalog/namespace.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index c009e9c241a..ac30f77f024 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -3868,12 +3868,31 @@ RemoveTempRelationsCallback(int code, Datum arg) /* * Remove all temp tables from the temporary namespace. + * + * If we haven't set up one yet, but one exists from a previous crashed + * backend, clean that one; but only do this once in a session's life. */ void ResetTempTableNamespace(void) { + static bool TempNamespaceCleaned = false; + if (OidIsValid(myTempNamespace)) RemoveTempRelations(myTempNamespace); + else if (MyBackendId != InvalidBackendId && !RecoveryInProgress() && + !TempNamespaceCleaned) + { + char namespaceName[NAMEDATALEN]; + Oid namespaceId; + + snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d", + MyBackendId); + namespaceId = get_namespace_oid(namespaceName, true); + if (OidIsValid(namespaceId)) + RemoveTempRelations(namespaceId); + } + + TempNamespaceCleaned = true; } [parent: a85045cccb1b]