From: Tomas Vondra Date: Sat, 14 Oct 2017 10:38:06 +0000 (+0200) Subject: Allocate thread-local snapshot array statically X-Git-Tag: XL_10_R1BETA1~103 X-Git-Url: http://git.postgresql.org/gitweb/?a=commitdiff_plain;h=1078b079d5476e3447bd5268b317eacb4c455f5d;p=postgres-xl.git 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 , investigation and fix by me. For more discussion see Backpatch to Postgres-XL 9.5. --- 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