summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Vondra2017-10-14 10:38:06 +0000
committerTomas Vondra2017-10-14 10:52:04 +0000
commit1078b079d5476e3447bd5268b317eacb4c455f5d (patch)
tree9efbd40a8be0b13e769e2fe54885828bcaed3cd3
parent1c7637f35f5f8b4566c4483f02041e7fc89a83cc (diff)
Allocate thread-local snapshot array statically
Since commit fb56418d66 the snapshots are computed in thread-local storage, but we haven't been freeing the memory (on thread exit). As the memory is allocated in the global (TopMostMemoryContext), this presented a memory leak of 64kB on each GTM connection. One way to fix this would be to track when the thread-local storage is used in GTM_GetTransactionSnapshot(), and allocate the memory in TopMemoryContext (which is per-thread and released on exit). But there's a simpler way - allocate the thread-specific storage as part of GTM_ThreadInfo, and just redirect sn_xip from the snapshot. This way we don't have to worry about palloc/pfree at all, and we mostly assume that every connection will need to compute at least one snapshot anyway. Reported by Rob Canavan <[email protected]>, investigation and fix by me. For more discussion see <CAFTg0q6VC_11+c=Q=gsAcDsBrDjvuGKjzNwH4Lr8vERRDn4Ycw@mail.gmail.com> Backpatch to Postgres-XL 9.5.
-rw-r--r--src/gtm/main/gtm_snap.c4
-rw-r--r--src/gtm/main/gtm_thread.c5
-rw-r--r--src/include/gtm/gtm.h7
3 files changed, 16 insertions, 0 deletions
diff --git a/src/gtm/main/gtm_snap.c b/src/gtm/main/gtm_snap.c
index 5a538985df..f8e3d31976 100644
--- a/src/gtm/main/gtm_snap.c
+++ b/src/gtm/main/gtm_snap.c
@@ -103,6 +103,10 @@ GTM_GetTransactionSnapshot(GTM_TransactionHandle handle[], int txn_count, int *s
Assert(snapshot != NULL);
+ /*
+ * This can only happen when using a snapshot from GTMTransactions, as the
+ * thread-specific sn_xip array is allocated statically as part of GTM_ThreadInfo.
+ */
if (snapshot->sn_xip == NULL)
{
/*
diff --git a/src/gtm/main/gtm_thread.c b/src/gtm/main/gtm_thread.c
index c513f6a71f..9d166f4a0e 100644
--- a/src/gtm/main/gtm_thread.c
+++ b/src/gtm/main/gtm_thread.c
@@ -256,6 +256,11 @@ GTM_ThreadCreate(GTM_ConnectionInfo *conninfo,
8 * 1024,
false);
+ /*
+ * Set the sn_xip pointer to the statically-allocated array (see GTM_ThreadInfo).
+ */
+ thrinfo->thr_snapshot.sn_xip = thrinfo->thr_xip;
+
thrinfo->thr_startroutine = startroutine;
/*
diff --git a/src/include/gtm/gtm.h b/src/include/gtm/gtm.h
index 37d31f6ba4..7b494fb6a2 100644
--- a/src/include/gtm/gtm.h
+++ b/src/include/gtm/gtm.h
@@ -59,6 +59,13 @@ typedef struct GTM_ThreadInfo
GTM_RWLock thr_lock;
gtm_List *thr_cached_txninfo;
GTM_SnapshotData thr_snapshot;
+
+ /*
+ * Statically allocated XID array for the snapshot. Every thread will need
+ * a snapshot anyway, and this way we don't have to worry about allocation
+ * and freeing of the memory at thread exit.
+ */
+ GlobalTransactionId thr_xip[GTM_MAX_GLOBAL_TRANSACTIONS];
} GTM_ThreadInfo;
typedef struct GTM_Threads