Skip to content

Commit 478afca

Browse files
committed
2 parents c57e0d1 + 19d8b84 commit 478afca

File tree

3 files changed

+170
-8
lines changed

3 files changed

+170
-8
lines changed

contrib/mmts/multimaster.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ typedef struct {
6363
csn_t snapshot; /* transaction snaphsot */
6464
} MtmCurrentTrans;
6565

66+
/* #define USE_SPINLOCK 1 */
67+
6668
typedef uint64 timestamp_t;
6769

6870
#define MTM_SHMEM_SIZE (64*1024*1024)
@@ -144,7 +146,7 @@ static void MtmProcessUtility(Node *parsetree, const char *queryString,
144146
void MtmLock(LWLockMode mode)
145147
{
146148
#ifdef USE_SPINLOCK
147-
SpinLockAcquire(&ds->hashSpinlock);
149+
SpinLockAcquire(&dtm->hashSpinlock);
148150
#else
149151
LWLockAcquire(dtm->hashLock, mode);
150152
#endif
@@ -153,7 +155,7 @@ void MtmLock(LWLockMode mode)
153155
void MtmUnlock(void)
154156
{
155157
#ifdef USE_SPINLOCK
156-
SpinLockRelease(&ds->hashSpinlock);
158+
SpinLockRelease(&dtm->hashSpinlock);
157159
#else
158160
LWLockRelease(dtm->hashLock);
159161
#endif

contrib/mmts/tests/dtmbench

8.12 KB
Binary file not shown.

contrib/pg_tsdtm/t/001_distributed_transactions.pl

Lines changed: 166 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
###############################################################################
22
# Test of proper transaction isolation.
3-
# Based on Martin Kleppmann tests, https://github.com/ept/hermitage
3+
# Based on Martin Kleppmann's tests set, https://github.com/ept/hermitage
44
###############################################################################
55

66
use strict;
77
use warnings;
88
use PostgresNode;
99
use TestLib;
10-
use Test::More tests => 2;
10+
use Test::More tests => 7;
1111
use DBI;
1212
use DBD::Pg ':async';
1313

@@ -16,7 +16,7 @@ sub query_row
1616
my ($dbi, $sql, @keys) = @_;
1717
my $sth = $dbi->prepare($sql) || die;
1818
$sth->execute(@keys) || die;
19-
my $ret = $sth->fetchrow_array;
19+
my $ret = $sth->fetchrow_array || undef;
2020
print "query_row('$sql') -> $ret \n";
2121
return $ret;
2222
}
@@ -81,11 +81,13 @@ sub PostgresNode::psql_fails {
8181
$node2->psql('postgres', "create table t(id int primary key, v int)");
8282
$node2->psql('postgres', "insert into t values(2, 20)");
8383

84-
# we need two connections to each node (run two simultameous global tx)
84+
# we will run up to three simultaneous tx, so six connections
8585
my $conn1a = DBI->connect('DBI:Pg:' . $node1->connstr('postgres'));
8686
my $conn2a = DBI->connect('DBI:Pg:' . $node2->connstr('postgres'));
8787
my $conn1b = DBI->connect('DBI:Pg:' . $node1->connstr('postgres'));
8888
my $conn2b = DBI->connect('DBI:Pg:' . $node2->connstr('postgres'));
89+
my $conn1c = DBI->connect('DBI:Pg:' . $node1->connstr('postgres'));
90+
my $conn2c = DBI->connect('DBI:Pg:' . $node2->connstr('postgres'));
8991

9092
sub count_total
9193
{
@@ -135,6 +137,12 @@ sub commit_global
135137
query_exec($c2, "commit prepared '$gtid'");
136138
}
137139

140+
# deadlock check!
141+
142+
# simple for share/update (examples in pg isolation tests)
143+
144+
145+
138146
###############################################################################
139147
# Sanity check for dirty reads
140148
###############################################################################
@@ -152,7 +160,7 @@ sub commit_global
152160
is($intermediate_total, 30, "Check for absence of dirty reads");
153161

154162
###############################################################################
155-
# G0
163+
# G0: Write Cycles
156164
###############################################################################
157165

158166
my $fail = 0;
@@ -188,7 +196,159 @@ sub commit_global
188196

189197
$fail = 1 if $v1 != 12 or $v2 != 22;
190198

191-
is($fail, 0, "Global transactions prevents Write Cycles (G0)");
199+
is($fail, 0, "Write Cycles (G0)");
200+
201+
###############################################################################
202+
# G1b: Intermediate Reads
203+
###############################################################################
204+
205+
$fail = 0;
206+
$node1->psql('postgres', "update t set v = 10 where id = 1");
207+
$node2->psql('postgres', "update t set v = 20 where id = 2");
208+
209+
start_global("G1b-a", $conn1a, $conn2a);
210+
start_global("G1b-b", $conn1b, $conn2b);
211+
212+
query_exec($conn1a, "update t set v = 101 where id = 1");
213+
214+
$v1 = query_row($conn1b, "select v from t where id = 1");
215+
$fail = 1 if $v1 != 10;
216+
217+
query_exec($conn1a, "update t set v = 11 where id = 1");
218+
commit_global("G1b-a", $conn1a, $conn2a);
219+
220+
$v1 = query_row($conn1b, "select v from t where id = 1");
221+
$fail = 1 if $v1 == 101;
222+
223+
if ($v1 != 11) {
224+
print "WARNIG: behavior is stricter than in usual read commited\n"
225+
}
226+
227+
commit_global("G1b-b", $conn1b, $conn2b);
228+
229+
is($fail, 0, "Intermediate Reads (G1b)");
230+
231+
232+
###############################################################################
233+
# G1c: Circular Information Flow
234+
###############################################################################
235+
236+
$fail = 0;
237+
$node1->psql('postgres', "update t set v = 10 where id = 1");
238+
$node2->psql('postgres', "update t set v = 20 where id = 2");
239+
240+
start_global("G1c-a", $conn1a, $conn2a);
241+
start_global("G1c-b", $conn1b, $conn2b);
242+
243+
query_exec($conn1a, "update t set v = 11 where id = 1");
244+
query_exec($conn2b, "update t set v = 22 where id = 2");
245+
246+
$v2 = query_row($conn2a, "select v from t where id = 2");
247+
$v1 = query_row($conn1b, "select v from t where id = 1");
248+
249+
$fail = 1 if $v1 != 10 or $v2 != 20;
250+
251+
commit_global("G1c-a", $conn1a, $conn2a);
252+
commit_global("G1c-b", $conn1b, $conn2b);
253+
254+
is($fail, 0, "Circular Information Flow (G1c)");
255+
256+
257+
###############################################################################
258+
# OTV: Observed Transaction Vanishes
259+
###############################################################################
260+
261+
$fail = 0;
262+
$node1->psql('postgres', "update t set v = 10 where id = 1");
263+
$node2->psql('postgres', "update t set v = 20 where id = 2");
264+
265+
start_global("OTV-a", $conn1a, $conn2a);
266+
start_global("OTV-b", $conn1b, $conn2b);
267+
start_global("OTV-c", $conn1c, $conn2c);
268+
269+
query_exec($conn1a, "update t set v = 11 where id = 1");
270+
query_exec($conn2a, "update t set v = 19 where id = 2");
271+
272+
query_exec_async($conn1b, "update t set v = 12 where id = 1");
273+
$fail = 1 if $conn1b->pg_ready != 0; # blocks
274+
commit_global("OTV-a", $conn1a, $conn2a);
275+
$conn1b->pg_result; # wait for unblock
276+
277+
$v1 = query_row($conn1c, "select v from t where id = 1");
278+
$fail = 1 if $v1 != 11;
279+
280+
query_exec($conn2b, "update t set v = 18 where id = 2");
281+
282+
$v2 = query_row($conn2c, "select v from t where id = 2");
283+
$fail = 1 if $v2 != 19;
284+
285+
commit_global("OTV-b", $conn1b, $conn2b);
286+
287+
$v2 = query_row($conn2c, "select v from t where id = 2");
288+
$v1 = query_row($conn1c, "select v from t where id = 1");
289+
$fail = 1 if $v2 != 18 or $v1 != 12;
290+
291+
commit_global("OTV-c", $conn1c, $conn2c);
292+
293+
is($fail, 0, "Observed Transaction Vanishes (OTV)");
294+
295+
296+
###############################################################################
297+
# PMP: Predicate-Many-Preceders
298+
###############################################################################
299+
300+
$fail = 0;
301+
$node1->psql('postgres', "delete from t");
302+
$node2->psql('postgres', "delete from t");
303+
$node1->psql('postgres', "insert into t values(1, 10)");
304+
$node2->psql('postgres', "insert into t values(2, 20)");
305+
306+
start_global("PMP-a", $conn1a, $conn2a);
307+
start_global("PMP-b", $conn1b, $conn2b);
308+
309+
my $v3 = query_row($conn1a, "select v from t where v = 30"); # should run everywhere!
310+
311+
query_exec($conn1b, "update t set v = 18 where id = 3"); # try place on second node?
312+
commit_global("PMP-b", $conn1b, $conn2b);
313+
314+
$v3 = query_row($conn1a, "select v from t where v % 3 = 0");
315+
$fail = 1 if defined $v3;
316+
317+
commit_global("PMP-a", $conn1a, $conn2a);
318+
319+
is($fail, 0, "Predicate-Many-Preceders (PMP)");
320+
321+
322+
323+
###############################################################################
324+
# PMP: Predicate-Many-Preceders for write predicates
325+
###############################################################################
326+
327+
$fail = 0;
328+
$node1->psql('postgres', "delete from t");
329+
$node2->psql('postgres', "delete from t");
330+
$node1->psql('postgres', "insert into t values(1, 10)");
331+
$node2->psql('postgres', "insert into t values(2, 20)");
332+
333+
start_global("PMPwp-a", $conn1a, $conn2a);
334+
start_global("PMPwp-b", $conn1b, $conn2b);
335+
336+
query_exec($conn1a, "update t set v = v + 10");
337+
query_exec($conn2a, "update t set v = v + 10");
338+
339+
query_exec_async($conn1b, "delete from t where v = 20");
340+
query_exec_async($conn2b, "delete from t where v = 20");
341+
commit_global("PMPwp-a", $conn1a, $conn2a);
342+
$conn1b->pg_result;
343+
$conn2b->pg_result;
344+
345+
query_row($conn1a, "select v from t where v = 20");
346+
query_row($conn2a, "select v from t where v = 20");
347+
348+
commit_global("PMPwp-b", $conn1b, $conn2b);
349+
350+
is($fail, 0, "Predicate-Many-Preceders for write predicates (PMPwp)");
351+
192352

193353

194354

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy