Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1uAOjv-00Emrp-La for pgsql-hackers@arkaria.postgresql.org; Thu, 01 May 2025 07:53:52 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1uAOjs-001akL-TS for pgsql-hackers@arkaria.postgresql.org; Thu, 01 May 2025 07:53:49 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1uAOjs-001akD-Jt for pgsql-hackers@lists.postgresql.org; Thu, 01 May 2025 07:53:49 +0000 Received: from oss.nttdata.com ([49.212.34.109]) by makus.postgresql.org with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1uAOjq-000UL9-20 for pgsql-hackers@lists.postgresql.org; Thu, 01 May 2025 07:53:48 +0000 Received: from [192.168.11.5] (p1696134-ipoe.ipoe.ocn.ne.jp [118.0.93.133]) by oss.nttdata.com (Postfix) with ESMTPSA id D02AC61A55; Thu, 1 May 2025 16:53:41 +0900 (JST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at oss.nttdata.com Message-ID: Date: Thu, 1 May 2025 16:53:41 +0900 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: pgsql: Add function to log the memory contexts of specified backend pro To: Robert Haas , Fujii Masao Cc: PostgreSQL Hackers References: Content-Language: en-US From: Fujii Masao In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 2025/05/01 2:15, Robert Haas wrote: > On Tue, Apr 6, 2021 at 12:45 AM Fujii Masao wrote: >> Add function to log the memory contexts of specified backend process. > > Hi, > > I think this might need a recursion guard. I tried this: > > diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c > index dc4c600922d..b219a934034 100644 > --- a/src/backend/tcop/postgres.c > +++ b/src/backend/tcop/postgres.c > @@ -3532,7 +3532,7 @@ ProcessInterrupts(void) > if (ParallelMessagePending) > ProcessParallelMessages(); > > - if (LogMemoryContextPending) > + if (true) > ProcessLogMemoryContextInterrupt(); > > if (PublishMemoryContextPending) > diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h > index 72f5655fb34..867fd7b0ad5 100644 > --- a/src/include/miscadmin.h > +++ b/src/include/miscadmin.h > @@ -112,7 +112,7 @@ extern void ProcessInterrupts(void); > /* Test whether an interrupt is pending */ > #ifndef WIN32 > #define INTERRUPTS_PENDING_CONDITION() \ > - (unlikely(InterruptPending)) > + (unlikely(InterruptPending) || true) > #else > #define INTERRUPTS_PENDING_CONDITION() \ > (unlikely(UNBLOCKED_SIGNAL_QUEUE()) ? > pgwin32_dispatch_queued_signals() : 0, \ > > That immediately caused infinite recursion, ending in a core dump: > > frame #13: 0x0000000104607b00 > postgres`errfinish(filename=, lineno=, > funcname=) at elog.c:543:2 [opt] > frame #14: 0x0000000104637078 > postgres`ProcessLogMemoryContextInterrupt at mcxt.c:1392:2 [opt] > frame #15: 0x00000001044a901c postgres`ProcessInterrupts at > postgres.c:3536:3 [opt] > frame #16: 0x0000000104607b54 > postgres`errfinish(filename=, lineno=, > funcname=) at elog.c:608:2 [opt] [artificial] > frame #17: 0x0000000104637078 > postgres`ProcessLogMemoryContextInterrupt at mcxt.c:1392:2 [opt] > frame #18: 0x00000001044a901c postgres`ProcessInterrupts at > postgres.c:3536:3 [opt] > > > It might be unlikely that a process can be signalled fast enough to > actually fail in this way, but I'm not sure it's impossible, and I > think we should be defending against it. The most trivial recursion > guard would be HOLD_INTERRUPTS()/RESUME_INTERRUPTS() around > ProcessLogMemoryContextInterrupt(), but I think that's probably not > quite good enough because it would make the backend impervious to > pg_terminate_backend() while it's dumping memory contexts, and that > could be a long time if the write blocks. Just idea, what do you think about adding a flag to indicate whether ProcessLogMemoryContextInterrupt() is currently running? Then, when a backend receives a signal and ProcessLogMemoryContextInterrupt() is invoked, it can simply return immediately if the flag is already set like this: ------------------------------ @ -1383,8 +1383,14 @@ HandleGetMemoryContextInterrupt(void) void ProcessLogMemoryContextInterrupt(void) { + static bool loggingMemoryContext = false; + LogMemoryContextPending = false; + if (loggingMemoryContext) + return; + loggingMemoryContext = true; + /* * Use LOG_SERVER_ONLY to prevent this message from being sent to the * connected client. @@ -1406,6 +1412,8 @@ ProcessLogMemoryContextInterrupt(void) * details about individual siblings beyond 100 will not be large. */ MemoryContextStatsDetail(TopMemoryContext, 100, 100, false); + + loggingMemoryContext = false; } ------------------------------ This way, we can safely ignore overlapping pg_log_backend_memory_contexts() requests while the function is already running. Thoughts? Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION