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

Commita99922f

Browse files
committed
Avoid unnecessary failure in SELECT concurrent with ALTER NO INHERIT.
If a query against an inheritance tree runs concurrently with an ALTERTABLE that's disinheriting one of the tree members, it's possible to geta "could not find inherited attribute" error because after obtaining lockon the removed member, make_inh_translation_list sees that its columnshave attinhcount=0 and decides they aren't the columns it's looking for.An ideal fix, perhaps, would avoid including such a just-removed membertable in the query at all; but there seems no way to accomplish thatwithout adding expensive catalog rechecks or creating a likelihood ofdeadlocks. Instead, let's just drop the check on attinhcount. In thisway, a query that's included a just-disinherited child will stillsucceed, which is not a completely unreasonable behavior.This problem has existed for a long time, so back-patch to all supportedbranches. Also add an isolation test verifying related behaviors.Patch by me; the new isolation test is based on Kyotaro Horiguchi's work.Discussion:https://postgr.es/m/20170626.174612.23936762.horiguchi.kyotaro@lab.ntt.co.jp
1 parentff99d77 commita99922f

File tree

4 files changed

+97
-2
lines changed

4 files changed

+97
-2
lines changed

‎src/backend/optimizer/prep/prepunion.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,15 +1498,15 @@ make_inh_translation_list(Relation oldrelation, Relation newrelation,
14981498
*/
14991499
if (old_attno<newnatts&&
15001500
(att=new_tupdesc->attrs[old_attno])!=NULL&&
1501-
!att->attisdropped&&att->attinhcount!=0&&
1501+
!att->attisdropped&&
15021502
strcmp(attname,NameStr(att->attname))==0)
15031503
new_attno=old_attno;
15041504
else
15051505
{
15061506
for (new_attno=0;new_attno<newnatts;new_attno++)
15071507
{
15081508
att=new_tupdesc->attrs[new_attno];
1509-
if (!att->attisdropped&&att->attinhcount!=0&&
1509+
if (!att->attisdropped&&
15101510
strcmp(attname,NameStr(att->attname))==0)
15111511
break;
15121512
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
Parsed test spec with 2 sessions
2+
3+
starting permutation: s1b s1delc1 s2sel s1c s2sel
4+
step s1b: BEGIN;
5+
step s1delc1: ALTER TABLE c1 NO INHERIT p;
6+
step s2sel: SELECT SUM(a) FROM p; <waiting ...>
7+
step s1c: COMMIT;
8+
step s2sel: <... completed>
9+
sum
10+
11+
11
12+
step s2sel: SELECT SUM(a) FROM p;
13+
sum
14+
15+
1
16+
17+
starting permutation: s1b s1delc1 s1addc2 s2sel s1c s2sel
18+
step s1b: BEGIN;
19+
step s1delc1: ALTER TABLE c1 NO INHERIT p;
20+
step s1addc2: ALTER TABLE c2 INHERIT p;
21+
step s2sel: SELECT SUM(a) FROM p; <waiting ...>
22+
step s1c: COMMIT;
23+
step s2sel: <... completed>
24+
sum
25+
26+
11
27+
step s2sel: SELECT SUM(a) FROM p;
28+
sum
29+
30+
101
31+
32+
starting permutation: s1b s1dropc1 s2sel s1c s2sel
33+
step s1b: BEGIN;
34+
step s1dropc1: DROP TABLE c1;
35+
step s2sel: SELECT SUM(a) FROM p; <waiting ...>
36+
step s1c: COMMIT;
37+
step s2sel: <... completed>
38+
sum
39+
40+
1
41+
step s2sel: SELECT SUM(a) FROM p;
42+
sum
43+
44+
1
45+
46+
starting permutation: s1b s1delc1 s1modc1a s2sel s1c s2sel
47+
step s1b: BEGIN;
48+
step s1delc1: ALTER TABLE c1 NO INHERIT p;
49+
step s1modc1a: ALTER TABLE c1 ALTER COLUMN a TYPE float;
50+
step s2sel: SELECT SUM(a) FROM p; <waiting ...>
51+
step s1c: COMMIT;
52+
step s2sel: <... completed>
53+
error in steps s1c s2sel: ERROR: attribute "a" of relation "c1" does not match parent's type
54+
step s2sel: SELECT SUM(a) FROM p;
55+
sum
56+
57+
1

‎src/test/isolation/isolation_schedule

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,6 @@ test: multiple-cic
5050
test: alter-table-1
5151
test: alter-table-2
5252
test: alter-table-3
53+
test: alter-table-4
5354
test: create-trigger
5455
test: timeouts
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# ALTER TABLE - Add and remove inheritance with concurrent reads
2+
3+
setup
4+
{
5+
CREATETABLEp (ainteger);
6+
INSERTINTOpVALUES(1);
7+
CREATETABLEc1 ()INHERITS (p);
8+
INSERTINTOc1VALUES(10);
9+
CREATETABLEc2 (ainteger);
10+
INSERTINTOc2VALUES(100);
11+
}
12+
13+
teardown
14+
{
15+
DROPTABLEIFEXISTSc1,c2,p;
16+
}
17+
18+
session"s1"
19+
step"s1b"{BEGIN; }
20+
step"s1delc1"{ALTERTABLEc1NOINHERITp; }
21+
step"s1modc1a"{ALTERTABLEc1ALTERCOLUMNaTYPEfloat; }
22+
step"s1addc2"{ALTERTABLEc2INHERITp; }
23+
step"s1dropc1"{DROPTABLEc1; }
24+
step"s1c"{COMMIT; }
25+
26+
session"s2"
27+
step"s2sel"{SELECTSUM(a)FROMp; }
28+
29+
# NO INHERIT will not be visible to concurrent select,
30+
# since we identify children before locking them
31+
permutation"s1b""s1delc1""s2sel""s1c""s2sel"
32+
# adding inheritance likewise is not seen if s1 commits after s2 locks p
33+
permutation"s1b""s1delc1""s1addc2""s2sel""s1c""s2sel"
34+
# but we do cope with DROP on a child table
35+
permutation"s1b""s1dropc1""s2sel""s1c""s2sel"
36+
# this case currently results in an error; doesn't seem worth preventing
37+
permutation"s1b""s1delc1""s1modc1a""s2sel""s1c""s2sel"

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp