diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c index fbc05f0dc13..cb1f3586d4c 100644 --- a/src/backend/storage/ipc/shmem.c +++ b/src/backend/storage/ipc/shmem.c @@ -917,15 +917,18 @@ ShmemResizeStruct(const char *name, Size new_size) * When shrinking, release memory pages beyond the new end, but not the * page containing maximal end of the structure, as it may be used by the * next structure. - * - * We do not consider the current end of the structure as it simplifies - * the calculations. Instead we rely on the underlying APIs not to touch - * the memory pages that will not be affected by the change in size. */ new_end = (char *) TYPEALIGN(page_size, (char *) result->location + new_size); if (new_size < result->size) { - char *max_end = (char *) TYPEALIGN_DOWN(page_size, (char *) result->location + result->maximum_size); + /* + * Only pages currently RW should be freed; anything past result->size + * is PROT_NONE reserved tail. Also stop before the last page shared + * with the next structure. + */ + char *current_end = (char *) TYPEALIGN(page_size, (char *) result->location + result->size); + char *reserved_end = (char *) TYPEALIGN_DOWN(page_size, (char *) result->location + result->maximum_size); + char *max_end = Min(current_end, reserved_end); if (max_end > new_end) {