Hi Simon, Hi all,

if (!logged && (wait_s > 0 || wait_us > 500000))
{
        const char *oldactivitymsg;
        int                     len;

        oldactivitymsg = get_ps_display(&len);
        snprintf(waitactivitymsg, sizeof(waitactivitymsg),
                         "waiting for max_standby_delay (%u s)",
                         MaxStandbyDelay);
        set_ps_display(waitactivitymsg, false);
        if (len > 100)
                len = 100;
        memcpy(waitactivitymsg, oldactivitymsg, len);

        pgstat_report_waiting(true);

        logged = true;
}
..
if (logged)
{
        set_ps_display(waitactivitymsg, false);
        pgstat_report_waiting(false);
}

That doesnt work because get_ps_display returns the internal buffer. This 
leads to the situation that after conflict resolution the 
"waiting for max_standby_delay ..."
message is displayed until the next segment starts where its replaced
again by the 
"... recovering ..." line.

Additionally the old code may print unintialized memory if get_ps_display
 returns a string without a \0 terminator.

The attached patch fixes that.

Andres
From a0198eab28552b9af9a70298f49a17348077c6fd Mon Sep 17 00:00:00 2001
From: Andres Freund <and...@anarazel.de>
Date: Sun, 7 Feb 2010 19:52:07 +0100
Subject: [PATCH] The stat reporting in ResolveRecoveryConflictWithVirtualXIDs had a
 small bug - it tried to use the buffer returned by get_ps_display() as
 temp. storage - which does not work.

---
 src/backend/storage/ipc/standby.c |   17 +++++++++++------
 1 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c
index 63a9c68..995a2dc 100644
*** a/src/backend/storage/ipc/standby.c
--- b/src/backend/storage/ipc/standby.c
*************** ResolveRecoveryConflictWithVirtualXIDs(V
*** 161,166 ****
--- 161,167 ----
  									   ProcSignalReason reason)
  {
  	char		waitactivitymsg[100];
+ 	char		oldactivitymsg[101];
  
  	while (VirtualTransactionIdIsValid(*waitlist))
  	{
*************** ResolveRecoveryConflictWithVirtualXIDs(V
*** 183,199 ****
  			TimestampDifference(waitStart, now, &wait_s, &wait_us);
  			if (!logged && (wait_s > 0 || wait_us > 500000))
  			{
! 				const char *oldactivitymsg;
  				int			len;
  
! 				oldactivitymsg = get_ps_display(&len);
  				snprintf(waitactivitymsg, sizeof(waitactivitymsg),
  						 "waiting for max_standby_delay (%u s)",
  						 MaxStandbyDelay);
  				set_ps_display(waitactivitymsg, false);
- 				if (len > 100)
- 					len = 100;
- 				memcpy(waitactivitymsg, oldactivitymsg, len);
  
  				pgstat_report_waiting(true);
  
--- 184,204 ----
  			TimestampDifference(waitStart, now, &wait_s, &wait_us);
  			if (!logged && (wait_s > 0 || wait_us > 500000))
  			{
! 				const char *oldactivitymsgp;
  				int			len;
  
! 				oldactivitymsgp = get_ps_display(&len);
! 
! 				if (len > 100)
! 					len = 100;
! 
! 				memcpy(oldactivitymsg, oldactivitymsgp, len);
! 				oldactivitymsg[len] = 0;
! 
  				snprintf(waitactivitymsg, sizeof(waitactivitymsg),
  						 "waiting for max_standby_delay (%u s)",
  						 MaxStandbyDelay);
  				set_ps_display(waitactivitymsg, false);
  
  				pgstat_report_waiting(true);
  
*************** ResolveRecoveryConflictWithVirtualXIDs(V
*** 223,229 ****
  		/* Reset ps display */
  		if (logged)
  		{
! 			set_ps_display(waitactivitymsg, false);
  			pgstat_report_waiting(false);
  		}
  
--- 228,234 ----
  		/* Reset ps display */
  		if (logged)
  		{
! 			set_ps_display(oldactivitymsg, false);
  			pgstat_report_waiting(false);
  		}
  
-- 
1.6.5.12.gd65df24

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to