Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita0f55fc

Browse files
committed
Fix assert failures in parallel SERIALIZABLE READ ONLY.
1. Make sure that we don't decrement SxactGlobalXminCount twice whenthe SXACT_FLAG_RO_SAFE optimization is reached in a parallel query.This could trigger a sanity check failure in assert builds. Non-assertbuilds recompute the count in SetNewSxactGlobalXmin(), so the problemwas hidden, explaining the lack of field reports. Add a new isolationtest to exercise that case.2. Remove an assertion that the DOOMED flag can't be set on a partiallyreleased SERIALIZABLEXACT. Instead, ignore the flag (our transactionwas already determined to be read-only safe, and DOOMED is in fact setduring partial release, and there was already an assertion that itwasn't set sooner). Improve an existing isolation test so that itreaches that case (previously it wasn't quite testing what it wassupposed to be testing; see discussion).Back-patch to 12. Bug #17116. Defects in commit47a338c.Reported-by: Alexander Lakhin <exclusion@gmail.com>Discussion:https://postgr.es/m/17116-d6ca217acc180e30%40postgresql.org
1 parent3b37e84 commita0f55fc

File tree

6 files changed

+184
-50
lines changed

6 files changed

+184
-50
lines changed

‎src/backend/storage/lmgr/predicate.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3337,6 +3337,7 @@ SetNewSxactGlobalXmin(void)
33373337
void
33383338
ReleasePredicateLocks(boolisCommit,boolisReadOnlySafe)
33393339
{
3340+
boolpartiallyReleasing= false;
33403341
boolneedToClear;
33413342
RWConflictconflict,
33423343
nextConflict,
@@ -3437,6 +3438,7 @@ ReleasePredicateLocks(bool isCommit, bool isReadOnlySafe)
34373438
else
34383439
{
34393440
MySerializableXact->flags |=SXACT_FLAG_PARTIALLY_RELEASED;
3441+
partiallyReleasing= true;
34403442
/* ... and proceed to perform the partial release below. */
34413443
}
34423444
}
@@ -3687,9 +3689,15 @@ ReleasePredicateLocks(bool isCommit, bool isReadOnlySafe)
36873689
* serializable transactions completes. We then find the "new oldest"
36883690
* xmin and purge any transactions which finished before this transaction
36893691
* was launched.
3692+
*
3693+
* For parallel queries in read-only transactions, it might run twice.
3694+
* We only release the reference on the first call.
36903695
*/
36913696
needToClear= false;
3692-
if (TransactionIdEquals(MySerializableXact->xmin,PredXact->SxactGlobalXmin))
3697+
if ((partiallyReleasing||
3698+
!SxactIsPartiallyReleased(MySerializableXact))&&
3699+
TransactionIdEquals(MySerializableXact->xmin,
3700+
PredXact->SxactGlobalXmin))
36933701
{
36943702
Assert(PredXact->SxactGlobalXminCount>0);
36953703
if (--(PredXact->SxactGlobalXminCount)==0)
@@ -4845,10 +4853,14 @@ PreCommit_CheckForSerializationFailure(void)
48454853

48464854
LWLockAcquire(SerializableXactHashLock,LW_EXCLUSIVE);
48474855

4848-
/* Check if someone else has already decided that we need to die */
4849-
if (SxactIsDoomed(MySerializableXact))
4856+
/*
4857+
* Check if someone else has already decided that we need to die. Since
4858+
* we set our own DOOMED flag when partially releasing, ignore in that
4859+
* case.
4860+
*/
4861+
if (SxactIsDoomed(MySerializableXact)&&
4862+
!SxactIsPartiallyReleased(MySerializableXact))
48504863
{
4851-
Assert(!SxactIsPartiallyReleased(MySerializableXact));
48524864
LWLockRelease(SerializableXactHashLock);
48534865
ereport(ERROR,
48544866
(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
Lines changed: 15 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,23 @@
11
Parsed test spec with 2 sessions
22

33
starting permutation: s1r s2r1 s1c s2r2 s2c
4-
step s1r: SELECT * FROM foo;
5-
a
6-
--
7-
1
8-
2
9-
3
10-
4
11-
5
12-
6
13-
7
14-
8
15-
9
16-
10
17-
(10 rows)
4+
step s1r: SELECT COUNT(*) FROM foo;
5+
count
6+
-----
7+
100
8+
(1 row)
189

19-
step s2r1: SELECT * FROM foo;
20-
a
21-
--
22-
1
23-
2
24-
3
25-
4
26-
5
27-
6
28-
7
29-
8
30-
9
31-
10
32-
(10 rows)
10+
step s2r1: SELECT COUNT(*) FROM foo;
11+
count
12+
-----
13+
100
14+
(1 row)
3315

3416
step s1c: COMMIT;
35-
step s2r2: SELECT * FROM foo;
36-
a
37-
--
38-
1
39-
2
40-
3
41-
4
42-
5
43-
6
44-
7
45-
8
46-
9
47-
10
48-
(10 rows)
17+
step s2r2: SELECT COUNT(*) FROM foo;
18+
count
19+
-----
20+
100
21+
(1 row)
4922

5023
step s2c: COMMIT;
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
Parsed test spec with 4 sessions
2+
3+
starting permutation: s1r s3r s2r1 s4r1 s1c s2r2 s3c s4r2 s4c s2c
4+
step s1r: SELECT * FROM foo;
5+
a
6+
--
7+
1
8+
2
9+
3
10+
4
11+
5
12+
6
13+
7
14+
8
15+
9
16+
10
17+
(10 rows)
18+
19+
step s3r: SELECT * FROM foo;
20+
a
21+
--
22+
1
23+
2
24+
3
25+
4
26+
5
27+
6
28+
7
29+
8
30+
9
31+
10
32+
(10 rows)
33+
34+
step s2r1: SELECT * FROM foo;
35+
a
36+
--
37+
1
38+
2
39+
3
40+
4
41+
5
42+
6
43+
7
44+
8
45+
9
46+
10
47+
(10 rows)
48+
49+
step s4r1: SELECT * FROM foo;
50+
a
51+
--
52+
1
53+
2
54+
3
55+
4
56+
5
57+
6
58+
7
59+
8
60+
9
61+
10
62+
(10 rows)
63+
64+
step s1c: COMMIT;
65+
step s2r2: SELECT * FROM foo;
66+
a
67+
--
68+
1
69+
2
70+
3
71+
4
72+
5
73+
6
74+
7
75+
8
76+
9
77+
10
78+
(10 rows)
79+
80+
step s3c: COMMIT;
81+
step s4r2: SELECT * FROM foo;
82+
a
83+
--
84+
1
85+
2
86+
3
87+
4
88+
5
89+
6
90+
7
91+
8
92+
9
93+
10
94+
(10 rows)
95+
96+
step s4c: COMMIT;
97+
step s2c: COMMIT;

‎src/test/isolation/isolation_schedule

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,4 @@ test: plpgsql-toast
9393
test: truncate-conflict
9494
test: serializable-parallel
9595
test: serializable-parallel-2
96+
test: serializable-parallel-3

‎src/test/isolation/specs/serializable-parallel-2.spec

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33

44
setup
55
{
6-
CREATETABLEfooASSELECTgenerate_series(1,10)::inta;
6+
CREATETABLEfooASSELECTgenerate_series(1,100)::inta;
7+
CREATEINDEXONfoo(a);
78
ALTERTABLEfooSET(parallel_workers=2);
89
}
910

@@ -14,17 +15,20 @@ teardown
1415

1516
sessions1
1617
setup{ BEGINTRANSACTIONISOLATIONLEVELSERIALIZABLE;}
17-
steps1r{SELECT*FROMfoo; }
18+
steps1r{SELECTCOUNT(*)FROMfoo;}
1819
steps1c{COMMIT;}
1920

2021
sessions2
2122
setup{
2223
BEGINTRANSACTIONISOLATIONLEVELSERIALIZABLEREADONLY;
2324
SETparallel_setup_cost=0;
2425
SETparallel_tuple_cost=0;
26+
SETmin_parallel_index_scan_size=0;
27+
SETparallel_leader_participation=off;
28+
SETenable_seqscan=off;
2529
}
26-
steps2r1{SELECT*FROMfoo; }
27-
steps2r2{SELECT*FROMfoo; }
30+
steps2r1{SELECTCOUNT(*)FROMfoo;}
31+
steps2r2{SELECTCOUNT(*)FROMfoo;}
2832
steps2c{COMMIT;}
2933

3034
permutations1rs2r1s1cs2r2s2c
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Exercise the case where a read-only serializable transaction has
2+
# SXACT_FLAG_RO_SAFE set in a parallel query. This variant is like
3+
# two copies of #2 running at the same time, and excercises the case
4+
# where another transaction has the same xmin, and it is the oldest.
5+
6+
setup
7+
{
8+
CREATETABLEfooASSELECTgenerate_series(1,10)::inta;
9+
ALTERTABLEfooSET(parallel_workers=2);
10+
}
11+
12+
teardown
13+
{
14+
DROPTABLEfoo;
15+
}
16+
17+
sessions1
18+
setup{ BEGINTRANSACTIONISOLATIONLEVELSERIALIZABLE;}
19+
steps1r{SELECT *FROMfoo;}
20+
steps1c{COMMIT;}
21+
22+
sessions2
23+
setup{
24+
BEGINTRANSACTIONISOLATIONLEVELSERIALIZABLEREADONLY;
25+
SETparallel_setup_cost=0;
26+
SETparallel_tuple_cost=0;
27+
}
28+
steps2r1{SELECT *FROMfoo;}
29+
steps2r2{SELECT *FROMfoo;}
30+
steps2c{COMMIT;}
31+
32+
sessions3
33+
setup{ BEGINTRANSACTIONISOLATIONLEVELSERIALIZABLE;}
34+
steps3r{SELECT *FROMfoo;}
35+
steps3c{COMMIT;}
36+
37+
sessions4
38+
setup{
39+
BEGINTRANSACTIONISOLATIONLEVELSERIALIZABLEREADONLY;
40+
SETparallel_setup_cost=0;
41+
SETparallel_tuple_cost=0;
42+
}
43+
steps4r1{SELECT *FROMfoo;}
44+
steps4r2{SELECT *FROMfoo;}
45+
steps4c{COMMIT;}
46+
47+
permutations1rs3rs2r1s4r1s1cs2r2s3cs4r2s4cs2c

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp