blob: 9936d389359e5f051c94621a5ff3dad35b049485 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
# GRANT's lock is the catalog tuple xmax. GRANT doesn't acquire a heavyweight
# lock on the object undergoing an ACL change. Inplace updates, such as
# relhasindex=true, need special code to cope.
setup
{
CREATE TABLE intra_grant_inplace (c int);
}
teardown
{
DROP TABLE IF EXISTS intra_grant_inplace;
}
# heap_update()
session s1
setup { SET deadlock_timeout = '100s'; }
step b1 { BEGIN; }
step grant1 {
GRANT SELECT ON intra_grant_inplace TO PUBLIC;
}
step drop1 {
DROP TABLE intra_grant_inplace;
}
step c1 { COMMIT; }
# inplace update
session s2
setup { SET deadlock_timeout = '10ms'; }
step read2 {
SELECT relhasindex FROM pg_class
WHERE oid = 'intra_grant_inplace'::regclass;
}
step b2 { BEGIN; }
step addk2 { ALTER TABLE intra_grant_inplace ADD PRIMARY KEY (c); }
step sfnku2 {
SELECT relhasindex FROM pg_class
WHERE oid = 'intra_grant_inplace'::regclass FOR NO KEY UPDATE;
}
step c2 { COMMIT; }
# rowmarks
session s3
step b3 { BEGIN ISOLATION LEVEL READ COMMITTED; }
step sfnku3 {
SELECT relhasindex FROM pg_class
WHERE oid = 'intra_grant_inplace'::regclass FOR NO KEY UPDATE;
}
step sfu3 {
SELECT relhasindex FROM pg_class
WHERE oid = 'intra_grant_inplace'::regclass FOR UPDATE;
}
step r3 { ROLLBACK; }
# Additional heap_update()
session s4
# swallow error message to keep any OID value out of expected output
step revoke4 {
DO $$
BEGIN
REVOKE SELECT ON intra_grant_inplace FROM PUBLIC;
EXCEPTION WHEN others THEN
RAISE WARNING 'got: %', regexp_replace(sqlerrm, '[0-9]+', 'REDACTED');
END
$$;
}
# Additional rowmarks
session s5
setup { BEGIN; }
step keyshr5 {
SELECT relhasindex FROM pg_class
WHERE oid = 'intra_grant_inplace'::regclass FOR KEY SHARE;
}
teardown { ROLLBACK; }
permutation
b1
grant1
read2
addk2(c1) # inplace waits
c1
read2
# inplace thru KEY SHARE
permutation
keyshr5
addk2
# inplace wait NO KEY UPDATE w/ KEY SHARE
permutation
keyshr5
b3
sfnku3
addk2(r3)
r3
# reproduce bug in DoesMultiXactIdConflict() call
permutation
b3
sfnku3
keyshr5
addk2(r3)
r3
# same-xact rowmark
permutation
b2
sfnku2
addk2
c2
# same-xact rowmark in multixact
permutation
keyshr5
b2
sfnku2
addk2
c2
permutation
b3
sfu3
b1
grant1(r3) # acquire LockTuple(), await sfu3 xmax
read2
addk2(c1) # block in LockTuple() behind grant1
r3 # unblock grant1; addk2 now awaits grant1 xmax
c1
read2
permutation
b2
sfnku2
b1
grant1(addk2) # acquire LockTuple(), await sfnku2 xmax
addk2(*) # block in LockTuple() behind grant1 = deadlock
c2
c1
read2
# SearchSysCacheLocked1() calling LockRelease()
permutation
b1
grant1
b3
sfu3(c1) # acquire LockTuple(), await grant1 xmax
revoke4(r3) # block in LockTuple() behind sfu3
c1
r3 # revoke4 unlocks old tuple and finds new
# SearchSysCacheLocked1() finding a tuple, then no tuple
permutation
b1
drop1
b3
sfu3(c1) # acquire LockTuple(), await drop1 xmax
revoke4(sfu3) # block in LockTuple() behind sfu3
c1 # sfu3 locks none; revoke4 unlocks old and finds none
r3
|