From f87cf67dd55d8800973cb1eb37f604aef5eb3154 Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Thu, 18 Oct 2018 10:48:18 +1300 Subject: [PATCH] Fix thinko in DSM control segment crash restart logic. If dsm_postmaster_shutdown() determines that the DSM control segment is corrupted, it should still destroy it, otherwise it is leaked and dsm_postmaster_startup() fails in an assertion that we are not currently attached to a control segment. Reported by build-farm animal peripatus. The root cause of the corrupted segment in that case is not yet known, but that's another matter. Author: Thomas Munro Diagnosed-by: Tom Lane Discussion: https://postgr.es/m/6153.1539806400%40sss.pgh.pa.us --- src/backend/storage/ipc/dsm.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/backend/storage/ipc/dsm.c b/src/backend/storage/ipc/dsm.c index 9629f22f7af..226fdee287a 100644 --- a/src/backend/storage/ipc/dsm.c +++ b/src/backend/storage/ipc/dsm.c @@ -138,8 +138,7 @@ static void *dsm_control_impl_private = NULL; /* * Start up the dynamic shared memory system. * - * This is called just once during each cluster lifetime, at postmaster - * startup time. + * This is called at postmaster startup time, and again during crash restarts. */ void dsm_postmaster_startup(PGShmemHeader *shim) @@ -234,14 +233,22 @@ dsm_cleanup_using_control_segment(dsm_handle old_control_handle) { dsm_impl_op(DSM_OP_DETACH, old_control_handle, 0, &impl_private, &mapped_address, &mapped_size, LOG); - return; + + /* + * This control segment doesn't look sane. We were previously + * attached to it, so we know that we created it and it's + * therefore safe to destroy it. It's not safe to destroy the list of + * segments that it points to though, because apparently the contents + * are corrupted, so we could inadvertently destroy segments belonging + * to some other software (say, another database cluster) running on + * the machine. Unfortunately this leaks the segments. + */ + nitems = 0; } + else + nitems = old_control->nitems; - /* - * OK, the control segment looks basically valid, so we can use it to get - * a list of segments that need to be removed. - */ - nitems = old_control->nitems; + /* Get a list of segments that need to be removed. */ for (i = 0; i < nitems; ++i) { dsm_handle handle; -- 2.17.1 (Apple Git-112)