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:21:51 +0000 (11:51 +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 1bea31b7d1b13ced9fe572abf68df707dafd48bf..f743b7c79cf1d2dba7716291e33691832982955d 100644 (file)
@@ -300,6 +300,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);
@@ -349,9 +350,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)
@@ -374,6 +378,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));
 
@@ -414,9 +419,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)