]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Release lock after encountering bogs row in vac_truncate_clog()
authorAndres Freund <andres@anarazel.de>
Thu, 13 Jul 2023 20:03:36 +0000 (13:03 -0700)
committerAndres Freund <andres@anarazel.de>
Thu, 13 Jul 2023 20:03:36 +0000 (13:03 -0700)
When vac_truncate_clog() encounters bogus datfrozenxid / datminmxid values, it
returns early. Unfortunately, until now, it did not release
WrapLimitsVacuumLock. If the backend later tries to acquire
WrapLimitsVacuumLock, the session / autovacuum worker hangs in an
uncancellable way. Similarly, other sessions will hang waiting for the
lock. However, if the backend holding the lock exited or errored out for some
reason, the lock was released.

The bug was introduced as a side effect of 566372b3d643.

It is interesting that there are no production reports of this problem. That
is likely due to a mix of bugs leading to bogus values having gotten less
common, process exit releasing locks and instances of hangs being hard to
debug for "normal" users.

Discussion: https://postgr.es/m/20230621221208.vhsqgduwfpzwxnpg@awork3.anarazel.de

src/backend/commands/vacuum.c

index 493a81c678126ef8cbc7338816a3ef4741f39ab0..794841e46c7c2db32f5b373f5d8d1f4a072575b3 100644 (file)
@@ -1590,12 +1590,16 @@ vac_truncate_clog(TransactionId frozenXID,
                ereport(WARNING,
                                (errmsg("some databases have not been vacuumed in over 2 billion transactions"),
                                 errdetail("You might have already suffered transaction-wraparound data loss.")));
+               LWLockRelease(WrapLimitsVacuumLock);
                return;
        }
 
        /* chicken out if data is bogus in any other way */
        if (bogus)
+       {
+               LWLockRelease(WrapLimitsVacuumLock);
                return;
+       }
 
        /*
         * Advance the oldest value for commit timestamps before truncating, so