On Wed, Nov 25, 2015 at 11:08 PM, Magnus Hagander <mag...@hagander.net>
wrote:

> On Wed, Nov 25, 2015 at 3:03 PM, Michael Paquier <
> michael.paqu...@gmail.com> wrote:
>
>> On Wed, Nov 25, 2015 at 7:18 PM, Magnus Hagander <mag...@hagander.net>
>> wrote:
>>
> In particular, it seems that in InitWalSenderSlot, we only initialize the
>>> sent location. Perhaps this is needed?
>>>
>>
>> Yes, that would be nice to start with a clean state. At the same time, I
>> am noticing that pg_stat_get_wal_senders() is comparing flush, apply and
>> write directly with 0. I think those should be InvalidXLogRecPtr. Combined
>> with your patch it gives the attached.
>>
>
> Good point.
>
> Another thought - why do we leave 0/0 in sent location, but turn the other
> three fields to NULL if it's invalid? That seems inconsistent. Is there a
> reason for that, or should we fix that as well while we're at it?
>

In some code paths, values are expected to be equal to 0 as XLogRecPtr
values are doing direct comparisons with each other, so you can think that
0 for a XLogRecPtr is slightly different from InvalidXLogRecPtr that could
be expected to be invalid but *not* minimal, imagine for example that we
decide at some point to redefine it as INT64_MAX. See for example
receivedUpto in xlog.c or WalSndWaitForWal in walsender.c. Honestly, I
think that it would be nice to make all the logic consistent under a unique
InvalidXLogRecPtr banner that is defined at 0 once and for all, adding at
the same time a comment in xlogdefs.h mentioning that this should not be
redefined to a higher value because comparison logic of XlogRecPtr's depend
on that. We have actually a similar constraint with TimeLineID = 0 that is
equivalent to infinite. Patch attached following those lines, which should
be backpatched for correctness.

Btw, I found at the same time a portion of NOT_USED code setting up a
XLogRecPtr incorrectly in GetOldestWALSendPointer.

FWIW, the last time I poked at this code, introducing some kind of
MinimalXLogRecPtr logic different to distinguish from InvalidXLogRecPtr I
hit a wall, others did not like that much:
http://www.postgresql.org/message-id/cab7npqruafytj024w-hiihw4pwfcadzn9hfmsjqfozsqtzt...@mail.gmail.com

Regards,
-- 
Michael
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index f17f834..3988ffd 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -191,7 +191,7 @@ HotStandbyState standbyState = STANDBY_DISABLED;
 static XLogRecPtr LastRec;
 
 /* Local copy of WalRcv->receivedUpto */
-static XLogRecPtr receivedUpto = 0;
+static XLogRecPtr receivedUpto = InvalidXLogRecPtr;
 static TimeLineID receiveTLI = 0;
 
 /*
@@ -4666,7 +4666,8 @@ XLOGShmemInit(void)
 	 */
 	allocptr = ((char *) XLogCtl) + sizeof(XLogCtlData);
 	XLogCtl->xlblocks = (XLogRecPtr *) allocptr;
-	memset(XLogCtl->xlblocks, 0, sizeof(XLogRecPtr) * XLOGbuffers);
+	memset(XLogCtl->xlblocks, InvalidXLogRecPtr,
+		   sizeof(XLogRecPtr) * XLOGbuffers);
 	allocptr += sizeof(XLogRecPtr) * XLOGbuffers;
 
 
@@ -11189,7 +11190,7 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess,
 						curFileTLI = tli;
 						RequestXLogStreaming(tli, ptr, PrimaryConnInfo,
 											 PrimarySlotName);
-						receivedUpto = 0;
+						receivedUpto = InvalidXLogRecPtr;
 					}
 
 					/*
@@ -11463,7 +11464,7 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess,
 static int
 emode_for_corrupt_record(int emode, XLogRecPtr RecPtr)
 {
-	static XLogRecPtr lastComplaint = 0;
+	static XLogRecPtr lastComplaint = InvalidXLogRecPtr;
 
 	if (readSource == XLOG_FROM_PG_XLOG && emode == LOG)
 	{
diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c
index 183a3a5..ccea4ca 100644
--- a/src/backend/replication/walreceiver.c
+++ b/src/backend/replication/walreceiver.c
@@ -1027,8 +1027,8 @@ XLogWalRcvFlush(bool dying)
 static void
 XLogWalRcvSendReply(bool force, bool requestReply)
 {
-	static XLogRecPtr writePtr = 0;
-	static XLogRecPtr flushPtr = 0;
+	static XLogRecPtr writePtr = InvalidXLogRecPtr;
+	static XLogRecPtr flushPtr = InvalidXLogRecPtr;
 	XLogRecPtr	applyPtr;
 	static TimestampTz sendTime = 0;
 	TimestampTz now;
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index 4a4643e..14b83b7 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -140,7 +140,7 @@ static XLogRecPtr sendTimeLineValidUpto = InvalidXLogRecPtr;
  * How far have we sent WAL already? This is also advertised in
  * MyWalSnd->sentPtr.  (Actually, this is the next WAL location to send.)
  */
-static XLogRecPtr sentPtr = 0;
+static XLogRecPtr sentPtr = InvalidXLogRecPtr;
 
 /* Buffers for constructing outgoing messages and processing reply messages. */
 static StringInfoData output_message;
@@ -1962,6 +1962,9 @@ InitWalSenderSlot(void)
 			 */
 			walsnd->pid = MyProcPid;
 			walsnd->sentPtr = InvalidXLogRecPtr;
+			walsnd->write = InvalidXLogRecPtr;
+			walsnd->flush = InvalidXLogRecPtr;
+			walsnd->apply = InvalidXLogRecPtr;
 			walsnd->state = WALSNDSTATE_STARTUP;
 			walsnd->latch = &MyProc->procLatch;
 			SpinLockRelease(&walsnd->mutex);
@@ -2819,17 +2822,20 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
 		else
 		{
 			values[1] = CStringGetTextDatum(WalSndGetStateString(state));
+
+			if (XLogRecPtrIsInvalid(sentPtr))
+				nulls[2] = true;
 			values[2] = LSNGetDatum(sentPtr);
 
-			if (write == 0)
+			if (XLogRecPtrIsInvalid(write))
 				nulls[3] = true;
 			values[3] = LSNGetDatum(write);
 
-			if (flush == 0)
+			if (XLogRecPtrIsInvalid(flush))
 				nulls[4] = true;
 			values[4] = LSNGetDatum(flush);
 
-			if (apply == 0)
+			if (XLogRecPtrIsInvalid(apply))
 				nulls[5] = true;
 			values[5] = LSNGetDatum(apply);
 
@@ -2933,7 +2939,7 @@ WalSndKeepaliveIfNecessary(TimestampTz now)
 XLogRecPtr
 GetOldestWALSendPointer(void)
 {
-	XLogRecPtr	oldest = {0, 0};
+	XLogRecPtr	oldest = InvalidXLogRecPtr;
 	int			i;
 	bool		found = false;
 
diff --git a/src/include/access/xlogdefs.h b/src/include/access/xlogdefs.h
index 18a3e7c..39a660c 100644
--- a/src/include/access/xlogdefs.h
+++ b/src/include/access/xlogdefs.h
@@ -23,7 +23,9 @@ typedef uint64 XLogRecPtr;
 /*
  * Zero is used indicate an invalid pointer. Bootstrap skips the first possible
  * WAL segment, initializing the first WAL page at XLOG_SEG_SIZE, so no XLOG
- * record can begin at zero.
+ * record can begin at zero. As direct comparisons of XLogRecPtr values depend
+ * on this default value being minimal, this should not be redefined to a
+ * higher value.
  */
 #define InvalidXLogRecPtr	0
 #define XLogRecPtrIsInvalid(r)	((r) == InvalidXLogRecPtr)
-- 
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