Skip to content

Commit b36e30c

Browse files
committed
Xid cache
1 parent edf5f00 commit b36e30c

File tree

6 files changed

+85
-15
lines changed

6 files changed

+85
-15
lines changed

contrib/mmts/multimaster.c

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -326,13 +326,41 @@ static char const* MtmGetName(void)
326326
* -------------------------------------------
327327
*/
328328

329+
static MtmTransState* MtmXidMapLookup(TransactionId xid)
330+
{
331+
MtmTransState* ts;
332+
if (TransactionIdPrecedes(xid, Mtm->oldestXid)) {
333+
Mtm->xidCacheSkips += 1;
334+
return NULL;
335+
}
336+
ts = Mtm->xidCache[xid % MULTIMASTER_XID_MAP_SIZE];
337+
if (ts != NULL && ts->xid == xid) {
338+
Mtm->xidCacheHits += 1;
339+
return ts;
340+
}
341+
Mtm->xidCacheMisses += 1;
342+
ts = hash_search(MtmXid2State, &xid, HASH_FIND, NULL);
343+
if (ts != NULL) {
344+
Mtm->xidCache[xid % MULTIMASTER_XID_MAP_SIZE] = ts;
345+
}
346+
return ts;
347+
}
348+
349+
static void MtmXidMapRemove(TransactionId xid)
350+
{
351+
MtmTransState* ts = hash_search(MtmXid2State, &xid, HASH_REMOVE, NULL);
352+
if (Mtm->xidCache[xid % MULTIMASTER_XID_MAP_SIZE] == ts) {
353+
Mtm->xidCache[xid % MULTIMASTER_XID_MAP_SIZE] = NULL;
354+
}
355+
}
356+
329357
csn_t MtmTransactionSnapshot(TransactionId xid)
330358
{
331359
MtmTransState* ts;
332360
csn_t snapshot = INVALID_CSN;
333361

334362
MtmLock(LW_SHARED);
335-
ts = hash_search(MtmXid2State, &xid, HASH_FIND, NULL);
363+
ts = MtmXidMapLookup(xid);
336364
if (ts != NULL && !ts->isLocal) {
337365
snapshot = ts->snapshot;
338366
}
@@ -384,7 +412,7 @@ bool MtmXidInMVCCSnapshot(TransactionId xid, Snapshot snapshot)
384412
#endif
385413
while (true)
386414
{
387-
MtmTransState* ts = (MtmTransState*)hash_search(MtmXid2State, &xid, HASH_FIND, NULL);
415+
MtmTransState* ts = MtmXidMapLookup(xid);
388416
if (ts != NULL && ts->status != TRANSACTION_STATUS_IN_PROGRESS)
389417
{
390418
if (ts->csn > MtmTx.snapshot) {
@@ -455,7 +483,7 @@ MtmAdjustOldestXid(TransactionId xid)
455483
int i;
456484
csn_t oldestSnapshot = INVALID_CSN;
457485
MtmTransState *prev = NULL;
458-
MtmTransState *ts = (MtmTransState*)hash_search(MtmXid2State, &xid, HASH_FIND, NULL);
486+
MtmTransState *ts = MtmXidMapLookup(xid);
459487
MTM_LOG2("%d: MtmAdjustOldestXid(%d): snapshot=%ld, csn=%ld, status=%d", MyProcPid, xid, ts != NULL ? ts->snapshot : 0, ts != NULL ? ts->csn : 0, ts != NULL ? ts->status : -1);
460488
Mtm->gcCount = 0;
461489
if (ts != NULL) {
@@ -480,7 +508,7 @@ MtmAdjustOldestXid(TransactionId xid)
480508
{
481509
if (prev != NULL) {
482510
/* Remove information about too old transactions */
483-
hash_search(MtmXid2State, &prev->xid, HASH_REMOVE, NULL);
511+
MtmXidMapRemove(prev->xid);
484512
}
485513
}
486514
}
@@ -657,6 +685,7 @@ MtmCreateTransState(MtmCurrentTrans* x)
657685
bool found;
658686
MtmTransState* ts = hash_search(MtmXid2State, &x->xid, HASH_ENTER, &found);
659687
if (!found) {
688+
Mtm->xidCache[x->xid % MULTIMASTER_XID_MAP_SIZE] = ts;
660689
ts->status = TRANSACTION_STATUS_IN_PROGRESS;
661690
ts->snapshot = x->snapshot;
662691
ts->isLocal = true;
@@ -743,7 +772,7 @@ MtmPostPrepareTransaction(MtmCurrentTrans* x)
743772
MtmTransState* ts;
744773

745774
MtmLock(LW_EXCLUSIVE);
746-
ts = hash_search(MtmXid2State, &x->xid, HASH_FIND, NULL);
775+
ts = MtmXidMapLookup(x->xid);
747776
Assert(ts != NULL);
748777

749778
if (!MtmIsCoordinator(ts) || Mtm->status == MTM_RECOVERY) {
@@ -810,7 +839,7 @@ MtmEndTransaction(MtmCurrentTrans* x, bool commit)
810839
MtmTransState* ts = NULL;
811840
MtmLock(LW_EXCLUSIVE);
812841
if (x->isPrepared) {
813-
ts = hash_search(MtmXid2State, &x->xid, HASH_FIND, NULL);
842+
ts = MtmXidMapLookup(x->xid);
814843
Assert(ts != NULL);
815844
} else if (x->gid[0]) {
816845
MtmTransMap* tm = (MtmTransMap*)hash_search(MtmGid2State, x->gid, HASH_REMOVE, NULL);
@@ -858,7 +887,7 @@ MtmEndTransaction(MtmCurrentTrans* x, bool commit)
858887
}
859888
MtmSendNotificationMessage(ts, MSG_ABORTED); /* send notification to coordinator */
860889
} else if (x->status == TRANSACTION_STATUS_ABORTED && x->isReplicated && !x->isPrepared) {
861-
hash_search(MtmXid2State, &x->xid, HASH_REMOVE, NULL);
890+
MtmXidMapRemove(x->xid);
862891
}
863892
MtmUnlock();
864893
}
@@ -960,7 +989,7 @@ csn_t MtmGetTransactionCSN(TransactionId xid)
960989
MtmTransState* ts;
961990
csn_t csn;
962991
MtmLock(LW_SHARED);
963-
ts = (MtmTransState*)hash_search(MtmXid2State, &xid, HASH_FIND, NULL);
992+
ts = MtmXidMapLookup(xid);
964993
Assert(ts != NULL);
965994
csn = ts->csn;
966995
MtmUnlock();
@@ -1207,6 +1236,9 @@ MtmBuildConnectivityMatrix(nodemask_t* matrix, bool nowait)
12071236
if (i+1 != MtmNodeId) {
12081237
void* data = RaftableGet(psprintf("node-mask-%d", i+1), NULL, NULL, nowait);
12091238
if (data == NULL) {
1239+
if (MtmUseRaftable) {
1240+
elog(WARNING, "Failed to get connectivity matrix from Raftable");
1241+
}
12101242
return false;
12111243
}
12121244
matrix[i] = *(nodemask_t*)data;
@@ -1491,6 +1523,8 @@ static void MtmInitialize()
14911523
Mtm->nodes[i].con = MtmConnections[i];
14921524
Mtm->nodes[i].flushPos = 0;
14931525
}
1526+
Mtm->xidCache = (MtmTransState**)ShmemAlloc(MULTIMASTER_XID_MAP_SIZE*sizeof(MtmTransState*));
1527+
memset(Mtm->xidCache, 0, MULTIMASTER_XID_MAP_SIZE*sizeof(MtmTransState*));
14941528
PGSemaphoreCreate(&Mtm->votingSemaphore);
14951529
PGSemaphoreReset(&Mtm->votingSemaphore);
14961530
SpinLockInit(&Mtm->spinlock);
@@ -2311,7 +2345,7 @@ mtm_get_csn(PG_FUNCTION_ARGS)
23112345
csn_t csn = INVALID_CSN;
23122346

23132347
MtmLock(LW_SHARED);
2314-
ts = hash_search(MtmXid2State, &xid, HASH_FIND, NULL);
2348+
ts = MtmXidMapLookup(xid);
23152349
if (ts != NULL) {
23162350
csn = ts->csn;
23172351
}
@@ -3036,7 +3070,7 @@ MtmGetGtid(TransactionId xid, GlobalTransactionId* gtid)
30363070
MtmTransState* ts;
30373071

30383072
MtmLock(LW_SHARED);
3039-
ts = (MtmTransState*)hash_search(MtmXid2State, &xid, HASH_FIND, NULL);
3073+
ts = MtmXidMapLookup(xid);
30403074
if (ts != NULL) {
30413075
*gtid = ts->gtid;
30423076
} else {
@@ -3121,6 +3155,9 @@ MtmDetectGlobalDeadLock(PGPROC* proc)
31213155
size_t size;
31223156
void* data = RaftableGet(psprintf("lock-graph-%d", i+1), &size, NULL, true);
31233157
if (data == NULL) {
3158+
if (MtmUseRaftable) {
3159+
elog(WARNING, "Failed to get deadlock graph from Raftable");
3160+
}
31243161
return true; /* If using Raftable is disabled */
31253162
} else {
31263163
MtmGraphAdd(&graph, (GlobalTransactionId*)data, size/sizeof(GlobalTransactionId));

contrib/mmts/multimaster.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#define MULTIMASTER_MAX_LOCAL_TABLES 256
4646
#define MULTIMASTER_BROADCAST_SERVICE "mtm_broadcast"
4747
#define MULTIMASTER_ADMIN "mtm_admin"
48+
#define MULTIMASTER_XID_MAP_SIZE (64*1024) /* should be power of two */
4849

4950
#define MB (1024*1024L)
5051

@@ -145,7 +146,7 @@ typedef struct MtmTransState
145146
struct MtmTransState* nextVoting; /* Next element in L1-list of voting transactions. */
146147
struct MtmTransState* next; /* Next element in L1 list of all finished transaction present in xid2state hash */
147148
bool votingCompleted; /* 2PC voting is completed */
148-
bool isLocal; /* Transaction is either replicated, either doesn't contain DML statements, so it shoudl be ignored by pglogical replication */
149+
bool isLocal; /* Transaction is either replicated, either doesn't contain DML statements, so it should be ignored by pglogical replication */
149150
TransactionId xids[1]; /* [Mtm->nAllNodes]: transaction ID at replicas */
150151
} MtmTransState;
151152

@@ -183,6 +184,10 @@ typedef struct
183184
uint64 transCount; /* Counter of transactions perfromed by this node */
184185
uint64 gcCount; /* Number of global transactions performed since last GC */
185186
BgwPool pool; /* Pool of background workers for applying logical replication patches */
187+
MtmTransState** xidCache; /* Fast cache for xid->state map */
188+
size_t xidCacheHits;
189+
size_t xidCacheMisses;
190+
size_t xidCacheSkips;
186191
MtmNodeInfo nodes[1]; /* [Mtm->nAllNodes]: per-node data */
187192
} MtmState;
188193

contrib/mmts/pglogical_apply.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -901,8 +901,8 @@ void MtmExecutor(int id, void* work, size_t size)
901901
StringInfoData s;
902902
Relation rel = NULL;
903903
int spill_file = -1;
904-
int save_cursor;
905-
int save_len;
904+
int save_cursor = 0;
905+
int save_len = 0;
906906
s.data = work;
907907
s.len = size;
908908
s.maxlen = -1;

contrib/mmts/tests/acid.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
- name: run transfers
4747
shell: >
4848
~/pg_cluster/install/bin/dtmacid {{connections}}
49-
-w {{ nconns }} -w 4 -r 2 -n 100000 -a 100 |
49+
-w {{ nconns }} -w 4 -r 2 -s -n 100000 -a 100 |
5050
tee -a perf.results |
5151
sed "s/^/`hostname`:/"
5252
register: transfers_result

contrib/mmts/tests/perf.results

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,3 +331,31 @@ Bench finished at Пт. апр. 15 18:43:05 MSK 2016
331331
Bench started at Пт. апр. 15 20:01:20 MSK 2016
332332
astro5:{tps:18310.750502, transactions:1500000, selects:0, updates:3001948, aborts:1897, abort_percent: 0, readers:0, writers:150, update_percent:100, accounts:500000, iterations:10000, hosts:3}
333333
Bench finished at Пт. апр. 15 20:02:42 MSK 2016
334+
Bench started at Пт. апр. 29 11:51:01 MSK 2016
335+
astro5:{tps:119545.326089, transactions:1000000, selects:2000000, updates:0, aborts:0, abort_percent: 0, readers:0, writers:100, update_percent:0, accounts:500000, iterations:10000, hosts:3}
336+
Bench finished at Пт. апр. 29 11:51:10 MSK 2016
337+
Bench started at Пт. апр. 29 11:52:28 MSK 2016
338+
astro5:{tps:16488.688858, transactions:1000000, selects:0, updates:2000764, aborts:384, abort_percent: 0, readers:0, writers:100, update_percent:100, accounts:500000, iterations:10000, hosts:3}
339+
Bench finished at Пт. апр. 29 11:53:29 MSK 2016
340+
Bench started at Пт. апр. 29 11:54:27 MSK 2016
341+
astro5:{tps:15606.584961, transactions:1000000, selects:0, updates:2000786, aborts:394, abort_percent: 0, readers:0, writers:100, update_percent:100, accounts:500000, iterations:10000, hosts:3}
342+
Bench finished at Пт. апр. 29 11:55:32 MSK 2016
343+
Bench started at Пт. апр. 29 11:56:37 MSK 2016
344+
astro5:lt=3852, gt=0
345+
astro5:lt=3642, gt=0
346+
astro5:{tps:222.570340, transactions:400000, selects:456842, updates:400000, aborts:4196, abort_percent: 1, readers:2, writers:4, update_percent:100, accounts:100, iterations:100000, hosts:3}
347+
Bench finished at Пт. апр. 29 12:26:34 MSK 2016
348+
Bench started at Пт. апр. 29 12:38:37 MSK 2016
349+
astro5:lt=1663, gt=0
350+
astro5:lt=1594, gt=0
351+
astro5:{tps:2370.486710, transactions:400000, selects:16168, updates:400000, aborts:0, abort_percent: 0, readers:2, writers:4, update_percent:100, accounts:100, iterations:100000, hosts:3}
352+
Bench finished at Пт. апр. 29 12:41:26 MSK 2016
353+
Bench started at Пт. апр. 29 12:49:24 MSK 2016
354+
astro5:{tps:16614.648418, transactions:1000000, selects:0, updates:2000878, aborts:440, abort_percent: 0, readers:0, writers:100, update_percent:100, accounts:500000, iterations:10000, hosts:3}
355+
Bench finished at Пт. апр. 29 12:50:25 MSK 2016
356+
Bench started at Пт. апр. 29 12:52:57 MSK 2016
357+
astro5:{tps:18162.135248, transactions:10000000, selects:0, updates:20008096, aborts:4075, abort_percent: 0, readers:0, writers:100, update_percent:100, accounts:500000, iterations:100000, hosts:3}
358+
Bench finished at Пт. апр. 29 13:02:08 MSK 2016
359+
Bench started at Пт. апр. 29 14:00:58 MSK 2016
360+
astro5:{tps:17705.596452, transactions:10000000, selects:0, updates:20007656, aborts:3840, abort_percent: 0, readers:0, writers:100, update_percent:100, accounts:500000, iterations:100000, hosts:3}
361+
Bench finished at Пт. апр. 29 14:10:23 MSK 2016

contrib/mmts/tests/perf.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
- name: run transfers
4747
shell: >
4848
~/pg_cluster/install/bin/dtmbench {{connections}}
49-
-w {{ nconns }} -r 0 -n 10000 -a 500000 -p {{ up }} |
49+
-w {{ nconns }} -r 0 -n 100000 -a 500000 -p {{ up }} |
5050
tee -a perf.results |
5151
sed "s/^/`hostname`:/"
5252
register: transfers_result

0 commit comments

Comments
 (0)