Fetch sn_xcnt just once to ensure consistent msg
authorPavan Deolasee <[email protected]>
Fri, 7 Sep 2018 06:08:51 +0000 (11:38 +0530)
committerPavan Deolasee <[email protected]>
Fri, 7 Sep 2018 06:08:51 +0000 (11:38 +0530)
We're seeing some reports when fetching snapshot from the GTM hangs forever on
the client side, waiting for data which never arrives. One theory is that the
snapshot->sn_xcnt value changes while sending snapshot from the GTM, thus
causing a mismatch between what the server sends and what the client expects.
We fixed a similar problem in 1078b079d5476e3447bd5268b317eacb4c455f5d, but may
be it's not complete. Put in this experimental patch (which can't make things
any worse for sure) while we also investigate other bugs in that area.

src/gtm/main/gtm_snap.c

index 1cd5f6377f7685570115c02a8ca5b56d4ee6289b..f5500656a5e82cc200200a61e54666e37368b15b 100644 (file)
@@ -379,6 +379,7 @@ ProcessGetSnapshotCommand(Port *myport, StringInfo message, bool get_gxid)
        int status;
        int txn_count;
        const char *data = NULL;
+       int sn_xcnt;
 
        txn_count = pq_getmsgint(message, sizeof (int));
        Assert(txn_count == 1);
@@ -428,9 +429,12 @@ ProcessGetSnapshotCommand(Port *myport, StringInfo message, bool get_gxid)
        pq_sendbytes(&buf, (char *)&status, sizeof(int) * txn_count);
        pq_sendbytes(&buf, (char *)&snapshot->sn_xmin, sizeof (GlobalTransactionId));
        pq_sendbytes(&buf, (char *)&snapshot->sn_xmax, sizeof (GlobalTransactionId));
-       pq_sendint(&buf, snapshot->sn_xcnt, sizeof (int));
+
+       /* Read once */
+       sn_xcnt = snapshot->sn_xcnt;
+       pq_sendint(&buf, sn_xcnt, sizeof (int));
        pq_sendbytes(&buf, (char *)snapshot->sn_xip,
-                                sizeof(GlobalTransactionId) * snapshot->sn_xcnt);
+                                sizeof(GlobalTransactionId) * sn_xcnt);
        pq_endmessage(myport, &buf);
 
        if (myport->remote_type != GTM_NODE_GTM_PROXY)
@@ -453,6 +457,7 @@ ProcessGetSnapshotCommandMulti(Port *myport, StringInfo message)
        int txn_count;
        int ii;
        int status[GTM_MAX_GLOBAL_TRANSACTIONS];
+       int sn_xcnt;
 
        txn_count = pq_getmsgint(message, sizeof (int));
 
@@ -493,9 +498,11 @@ ProcessGetSnapshotCommandMulti(Port *myport, StringInfo message)
        pq_sendbytes(&buf, (char *)status, sizeof(int) * txn_count);
        pq_sendbytes(&buf, (char *)&snapshot->sn_xmin, sizeof (GlobalTransactionId));
        pq_sendbytes(&buf, (char *)&snapshot->sn_xmax, sizeof (GlobalTransactionId));
-       pq_sendint(&buf, snapshot->sn_xcnt, sizeof (int));
+       /* Read once */
+       sn_xcnt = snapshot->sn_xcnt;
+       pq_sendint(&buf, sn_xcnt, sizeof (int));
        pq_sendbytes(&buf, (char *)snapshot->sn_xip,
-                                sizeof(GlobalTransactionId) * snapshot->sn_xcnt);
+                                sizeof(GlobalTransactionId) * sn_xcnt);
        pq_endmessage(myport, &buf);
 
        if (myport->remote_type != GTM_NODE_GTM_PROXY)