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

Commit1eea8e8

Browse files
committed
Fix bug in PreCommit_CheckForSerializationFailure. A transaction that has
already been marked as PREPARED cannot be killed. Kill the currenttransaction instead.One of the prepared_xacts regression tests actually hits this bug. Iremoved the anomaly from the duplicate-gids test so that it fails in theintended way, and added a new test to check serialization failures witha prepared transaction.Dan Ports
1 parent7cb2ff9 commit1eea8e8

File tree

3 files changed

+77
-7
lines changed

3 files changed

+77
-7
lines changed

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4542,6 +4542,21 @@ PreCommit_CheckForSerializationFailure(void)
45424542
&& !SxactIsReadOnly(farConflict->sxactOut)
45434543
&& !SxactIsDoomed(farConflict->sxactOut)))
45444544
{
4545+
/*
4546+
* Normally, we kill the pivot transaction to make sure we
4547+
* make progress if the failing transaction is retried.
4548+
* However, we can't kill it if it's already prepared, so
4549+
* in that case we commit suicide instead.
4550+
*/
4551+
if (SxactIsPrepared(nearConflict->sxactOut))
4552+
{
4553+
LWLockRelease(SerializableXactHashLock);
4554+
ereport(ERROR,
4555+
(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
4556+
errmsg("could not serialize access due to read/write dependencies among transactions"),
4557+
errdetail("Cancelled on commit attempt with conflict in from prepared pivot."),
4558+
errhint("The transaction might succeed if retried.")));
4559+
}
45454560
nearConflict->sxactOut->flags |=SXACT_FLAG_DOOMED;
45464561
break;
45474562
}

‎src/test/regress/expected/prepared_xacts.out

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,32 +88,67 @@ SELECT gid FROM pg_prepared_xacts;
8888

8989
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
9090
INSERT INTO pxtest1 VALUES ('fff');
91+
-- This should fail, because the gid foo3 is already in use
92+
PREPARE TRANSACTION 'foo3';
93+
ERROR: transaction identifier "foo3" is already in use
9194
SELECT * FROM pxtest1;
9295
foobar
9396
--------
9497
aaa
9598
ddd
96-
fff
97-
(3 rows)
99+
(2 rows)
98100

99-
-- This should fail, because the gid foo3 is already in use
100-
PREPARE TRANSACTION 'foo3';
101-
ERROR: transaction identifier "foo3" is already in use
101+
ROLLBACK PREPARED 'foo3';
102102
SELECT * FROM pxtest1;
103103
foobar
104104
--------
105105
aaa
106106
ddd
107107
(2 rows)
108108

109-
ROLLBACK PREPARED 'foo3';
109+
-- Test serialization failure (SSI)
110+
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
111+
UPDATE pxtest1 SET foobar = 'eee' WHERE foobar = 'ddd';
112+
SELECT * FROM pxtest1;
113+
foobar
114+
--------
115+
aaa
116+
eee
117+
(2 rows)
118+
119+
PREPARE TRANSACTION 'foo4';
120+
SELECT gid FROM pg_prepared_xacts;
121+
gid
122+
------
123+
foo4
124+
(1 row)
125+
126+
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
110127
SELECT * FROM pxtest1;
111128
foobar
112129
--------
113130
aaa
114131
ddd
115132
(2 rows)
116133

134+
INSERT INTO pxtest1 VALUES ('fff');
135+
-- This should fail, because the two transactions have a write-skew anomaly
136+
PREPARE TRANSACTION 'foo5';
137+
ERROR: could not serialize access due to read/write dependencies among transactions
138+
DETAIL: Cancelled on commit attempt with conflict in from prepared pivot.
139+
HINT: The transaction might succeed if retried.
140+
SELECT gid FROM pg_prepared_xacts;
141+
gid
142+
------
143+
foo4
144+
(1 row)
145+
146+
ROLLBACK PREPARED 'foo4';
147+
SELECT gid FROM pg_prepared_xacts;
148+
gid
149+
-----
150+
(0 rows)
151+
117152
-- Clean up
118153
DROP TABLE pxtest1;
119154
-- Test subtransactions

‎src/test/regress/sql/prepared_xacts.sql

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ SELECT gid FROM pg_prepared_xacts;
5454

5555
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
5656
INSERT INTO pxtest1VALUES ('fff');
57-
SELECT*FROM pxtest1;
5857

5958
-- This should fail, because the gid foo3 is already in use
6059
PREPARE TRANSACTION'foo3';
@@ -65,6 +64,27 @@ ROLLBACK PREPARED 'foo3';
6564

6665
SELECT*FROM pxtest1;
6766

67+
-- Test serialization failure (SSI)
68+
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
69+
UPDATE pxtest1SET foobar='eee'WHERE foobar='ddd';
70+
SELECT*FROM pxtest1;
71+
PREPARE TRANSACTION'foo4';
72+
73+
SELECT gidFROM pg_prepared_xacts;
74+
75+
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
76+
SELECT*FROM pxtest1;
77+
INSERT INTO pxtest1VALUES ('fff');
78+
79+
-- This should fail, because the two transactions have a write-skew anomaly
80+
PREPARE TRANSACTION'foo5';
81+
82+
SELECT gidFROM pg_prepared_xacts;
83+
84+
ROLLBACK PREPARED'foo4';
85+
86+
SELECT gidFROM pg_prepared_xacts;
87+
6888
-- Clean up
6989
DROPTABLE pxtest1;
7090

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp