mirror of
https://github.com/postgres/postgres.git
synced 2025-05-02 11:44:50 +03:00
Further effort at preventing memory map dump from affecting the results.
Rather than elog'ing immediately, push the map data into a preallocated StringInfo. Perhaps this will prevent some of the mid-operation allocations that are evidently happening now. Discussion: https://postgr.es/m/25495.1524517820@sss.pgh.pa.us
This commit is contained in:
parent
b04ebca6cd
commit
ce07aff48f
@ -12,6 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "lib/stringinfo.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "storage/dsm.h"
|
#include "storage/dsm.h"
|
||||||
#include "storage/ipc.h"
|
#include "storage/ipc.h"
|
||||||
@ -54,13 +55,17 @@ mi_state(DWORD code)
|
|||||||
return "???";
|
return "???";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Append memory dump to buf. To avoid affecting the memory map mid-run,
|
||||||
|
* buf should be preallocated to be bigger than needed.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
dumpmem(const char *reason)
|
dumpmem(StringInfo buf, const char *reason)
|
||||||
{
|
{
|
||||||
char *addr = 0;
|
char *addr = 0;
|
||||||
MEMORY_BASIC_INFORMATION mi;
|
MEMORY_BASIC_INFORMATION mi;
|
||||||
|
|
||||||
elog(LOG, "%s memory map", reason);
|
appendStringInfo(buf, "%s memory map:", reason);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
memset(&mi, 0, sizeof(mi));
|
memset(&mi, 0, sizeof(mi));
|
||||||
@ -68,12 +73,13 @@ dumpmem(const char *reason)
|
|||||||
{
|
{
|
||||||
if (GetLastError() == ERROR_INVALID_PARAMETER)
|
if (GetLastError() == ERROR_INVALID_PARAMETER)
|
||||||
break;
|
break;
|
||||||
elog(LOG, "VirtualQuery failed: %lu", GetLastError());
|
appendStringInfo(buf, "\nVirtualQuery failed: %lu", GetLastError());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
elog(LOG, "0x%p+0x%p %s (alloc 0x%p) %s",
|
appendStringInfo(buf, "\n0x%p+0x%p %s (alloc 0x%p) %s",
|
||||||
mi.BaseAddress, (void *) mi.RegionSize,
|
mi.BaseAddress, (void *) mi.RegionSize,
|
||||||
mi_type(mi.Type), mi.AllocationBase, mi_state(mi.State));
|
mi_type(mi.Type), mi.AllocationBase,
|
||||||
|
mi_state(mi.State));
|
||||||
addr += mi.RegionSize;
|
addr += mi.RegionSize;
|
||||||
} while (addr > 0);
|
} while (addr > 0);
|
||||||
}
|
}
|
||||||
@ -442,11 +448,16 @@ PGSharedMemoryReAttach(void)
|
|||||||
{
|
{
|
||||||
PGShmemHeader *hdr;
|
PGShmemHeader *hdr;
|
||||||
void *origUsedShmemSegAddr = UsedShmemSegAddr;
|
void *origUsedShmemSegAddr = UsedShmemSegAddr;
|
||||||
|
StringInfoData buf;
|
||||||
|
|
||||||
Assert(UsedShmemSegAddr != NULL);
|
Assert(UsedShmemSegAddr != NULL);
|
||||||
Assert(IsUnderPostmaster);
|
Assert(IsUnderPostmaster);
|
||||||
|
|
||||||
dumpmem("before VirtualFree");
|
/* Ensure buf is big enough that it won't grow mid-operation */
|
||||||
|
initStringInfo(&buf);
|
||||||
|
enlargeStringInfo(&buf, 128 * 1024);
|
||||||
|
|
||||||
|
dumpmem(&buf, "before VirtualFree");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Release memory region reservation that was made by the postmaster
|
* Release memory region reservation that was made by the postmaster
|
||||||
@ -455,20 +466,19 @@ PGSharedMemoryReAttach(void)
|
|||||||
elog(FATAL, "failed to release reserved memory region (addr=%p): error code %lu",
|
elog(FATAL, "failed to release reserved memory region (addr=%p): error code %lu",
|
||||||
UsedShmemSegAddr, GetLastError());
|
UsedShmemSegAddr, GetLastError());
|
||||||
|
|
||||||
dumpmem("after VirtualFree");
|
dumpmem(&buf, "after VirtualFree");
|
||||||
|
|
||||||
hdr = (PGShmemHeader *) MapViewOfFileEx(UsedShmemSegID, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0, UsedShmemSegAddr);
|
hdr = (PGShmemHeader *) MapViewOfFileEx(UsedShmemSegID, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0, UsedShmemSegAddr);
|
||||||
if (!hdr)
|
if (!hdr)
|
||||||
{
|
{
|
||||||
DWORD maperr = GetLastError();
|
DWORD maperr = GetLastError();
|
||||||
|
|
||||||
dumpmem("after failed MapViewOfFileEx");
|
dumpmem(&buf, "after failed MapViewOfFileEx");
|
||||||
|
elog(LOG, "%s", buf.data);
|
||||||
|
|
||||||
elog(FATAL, "could not reattach to shared memory (key=%p, addr=%p): error code %lu",
|
elog(FATAL, "could not reattach to shared memory (key=%p, addr=%p): error code %lu",
|
||||||
UsedShmemSegID, UsedShmemSegAddr, maperr);
|
UsedShmemSegID, UsedShmemSegAddr, maperr);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
dumpmem("after MapViewOfFileEx");
|
|
||||||
if (hdr != origUsedShmemSegAddr)
|
if (hdr != origUsedShmemSegAddr)
|
||||||
elog(FATAL, "reattaching to shared memory returned unexpected address (got %p, expected %p)",
|
elog(FATAL, "reattaching to shared memory returned unexpected address (got %p, expected %p)",
|
||||||
hdr, origUsedShmemSegAddr);
|
hdr, origUsedShmemSegAddr);
|
||||||
@ -476,6 +486,8 @@ PGSharedMemoryReAttach(void)
|
|||||||
elog(FATAL, "reattaching to shared memory returned non-PostgreSQL memory");
|
elog(FATAL, "reattaching to shared memory returned non-PostgreSQL memory");
|
||||||
dsm_set_control_handle(hdr->dsm_control);
|
dsm_set_control_handle(hdr->dsm_control);
|
||||||
|
|
||||||
|
pfree(buf.data);
|
||||||
|
|
||||||
UsedShmemSegAddr = hdr; /* probably redundant */
|
UsedShmemSegAddr = hdr; /* probably redundant */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user