diff options
author | Pavan Deolasee | 2014-10-16 11:49:25 +0000 |
---|---|---|
committer | Pavan Deolasee | 2015-04-15 05:41:30 +0000 |
commit | 3ad9d47b18de04cf352e8f0ac6e3338263db2bbb (patch) | |
tree | 61b821c9caad21f4a4871268d622b783de490a0b /src/backend/tcop/postgres.c | |
parent | 8312dd9d2ba27d6cfee6067221ad2265642552d5 (diff) |
Refactor snapshot management at datanode.
A snapshot build from local transaction information can be a source of many
bugs, one highlighted recently in the ML when a connection startup will build a
local snapshot and may compute a RecentXmin which is younger than what it
should really be. This can lead to all sorts of issues, most dangerous being
that HOT pruning can decide to prune away tuples which are not yet dead or
would never be dead.
This patch massively refactors the snapshot mechanism. We now soley rely on
either snapshots sent down by the coordinator or obtaining a direct snapshot
from the GTM. The only exception is during "initdb" time, when we allow local
snapshots. Even this should be tighened soon so that even initdb uses a GTM
supplied snapshot.
Diffstat (limited to 'src/backend/tcop/postgres.c')
-rw-r--r-- | src/backend/tcop/postgres.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index eb234a0806..137bc4fe33 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -3994,10 +3994,10 @@ PostgresMain(int argc, char *argv[], const char *username) #ifdef PGXC /* PGXC_DATANODE */ /* Snapshot info */ - int xmin; - int xmax; - int xcnt; - int *xip; + TransactionId xmin; + TransactionId xmax; + int xcnt; + TransactionId *xip; /* Timestamp info */ TimestampTz timestamp; #ifndef XCP @@ -4840,7 +4840,9 @@ PostgresMain(int argc, char *argv[], const char *username) case 'g': /* gxid */ { /* Set the GXID we were passed down */ - TransactionId gxid = (TransactionId) pq_getmsgint(&input_message, 4); + TransactionId gxid; + memcpy(&gxid, pq_getmsgbytes(&input_message, sizeof (TransactionId)), + sizeof (TransactionId)); elog(DEBUG1, "Received new gxid %u", gxid); SetNextTransactionId(gxid); pq_getmsgend(&input_message); @@ -4849,14 +4851,20 @@ PostgresMain(int argc, char *argv[], const char *username) case 's': /* snapshot */ /* Set the snapshot we were passed down */ - xmin = pq_getmsgint(&input_message, 4); - xmax = pq_getmsgint(&input_message, 4); - RecentGlobalXmin = pq_getmsgint(&input_message, 4); + memcpy(&xmin, + pq_getmsgbytes(&input_message, sizeof (TransactionId)), + sizeof (TransactionId)); + memcpy(&xmax, + pq_getmsgbytes(&input_message, sizeof (TransactionId)), + sizeof (TransactionId)); + memcpy(&RecentGlobalXmin, + pq_getmsgbytes(&input_message, sizeof (TransactionId)), + sizeof (TransactionId)); xcnt = pq_getmsgint(&input_message, 4); if (xcnt > 0) { int i; - xip = malloc(xcnt * sizeof(int)); + xip = palloc(xcnt * sizeof(TransactionId)); if (xip == NULL) { ereport(ERROR, @@ -4864,12 +4872,17 @@ PostgresMain(int argc, char *argv[], const char *username) errmsg("out of memory"))); } for (i = 0; i < xcnt; i++) - xip[i] = pq_getmsgint(&input_message, 4); + memcpy(&xip[i], + pq_getmsgbytes(&input_message, sizeof (TransactionId)), + sizeof (TransactionId)); } else xip = NULL; pq_getmsgend(&input_message); - SetGlobalSnapshotData(xmin, xmax, xcnt, xip); + SetGlobalSnapshotData(xmin, xmax, xcnt, xip, + SNAPSHOT_COORDINATOR); + if (xip) + pfree(xip); break; case 't': /* timestamp */ |