Skip to content

Commit 70fda58

Browse files
committed
Merge branch 'REL9_6_STABLE' into PGPRO9_6
Conflicts: doc/src/sgml/runtime.sgml
2 parents 333c3b4 + 6beb8c7 commit 70fda58

File tree

121 files changed

+5777
-1712
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

121 files changed

+5777
-1712
lines changed

contrib/pg_visibility/pg_visibility.c

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* pg_visibility.c
44
* display visibility map information and page-level visibility bits
55
*
6+
* Copyright (c) 2016, PostgreSQL Global Development Group
7+
*
68
* contrib/pg_visibility/pg_visibility.c
79
*-------------------------------------------------------------------------
810
*/
@@ -54,6 +56,10 @@ static bool tuple_all_visible(HeapTuple tup, TransactionId OldestXmin,
5456

5557
/*
5658
* Visibility map information for a single block of a relation.
59+
*
60+
* Note: the VM code will silently return zeroes for pages past the end
61+
* of the map, so we allow probes up to MaxBlockNumber regardless of the
62+
* actual relation size.
5763
*/
5864
Datum
5965
pg_visibility_map(PG_FUNCTION_ARGS)
@@ -122,13 +128,22 @@ pg_visibility(PG_FUNCTION_ARGS)
122128
values[0] = BoolGetDatum((mapbits & VISIBILITYMAP_ALL_VISIBLE) != 0);
123129
values[1] = BoolGetDatum((mapbits & VISIBILITYMAP_ALL_FROZEN) != 0);
124130

125-
buffer = ReadBuffer(rel, blkno);
126-
LockBuffer(buffer, BUFFER_LOCK_SHARE);
131+
/* Here we have to explicitly check rel size ... */
132+
if (blkno < RelationGetNumberOfBlocks(rel))
133+
{
134+
buffer = ReadBuffer(rel, blkno);
135+
LockBuffer(buffer, BUFFER_LOCK_SHARE);
127136

128-
page = BufferGetPage(buffer);
129-
values[2] = BoolGetDatum(PageIsAllVisible(page));
137+
page = BufferGetPage(buffer);
138+
values[2] = BoolGetDatum(PageIsAllVisible(page));
130139

131-
UnlockReleaseBuffer(buffer);
140+
UnlockReleaseBuffer(buffer);
141+
}
142+
else
143+
{
144+
/* As with the vismap, silently return 0 for pages past EOF */
145+
values[2] = BoolGetDatum(false);
146+
}
132147

133148
relation_close(rel, AccessShareLock);
134149

@@ -611,14 +626,13 @@ collect_corrupt_items(Oid relid, bool all_visible, bool all_frozen)
611626
/* Dead line pointers are neither all-visible nor frozen. */
612627
if (ItemIdIsDead(itemid))
613628
{
614-
ItemPointerData tid;
615-
616-
ItemPointerSet(&tid, blkno, offnum);
617-
record_corrupt_item(items, &tid);
629+
ItemPointerSet(&(tuple.t_self), blkno, offnum);
630+
record_corrupt_item(items, &tuple.t_self);
618631
continue;
619632
}
620633

621634
/* Initialize a HeapTupleData structure for checks below. */
635+
ItemPointerSet(&(tuple.t_self), blkno, offnum);
622636
tuple.t_data = (HeapTupleHeader) PageGetItem(page, itemid);
623637
tuple.t_len = ItemIdGetLength(itemid);
624638
tuple.t_tableOid = relid;
@@ -649,12 +663,12 @@ collect_corrupt_items(Oid relid, bool all_visible, bool all_frozen)
649663
RecomputedOldestXmin = GetOldestXmin(NULL, true);
650664

651665
if (!TransactionIdPrecedes(OldestXmin, RecomputedOldestXmin))
652-
record_corrupt_item(items, &tuple.t_data->t_ctid);
666+
record_corrupt_item(items, &tuple.t_self);
653667
else
654668
{
655669
OldestXmin = RecomputedOldestXmin;
656670
if (!tuple_all_visible(&tuple, OldestXmin, buffer))
657-
record_corrupt_item(items, &tuple.t_data->t_ctid);
671+
record_corrupt_item(items, &tuple.t_self);
658672
}
659673
}
660674

@@ -665,7 +679,7 @@ collect_corrupt_items(Oid relid, bool all_visible, bool all_frozen)
665679
if (check_frozen)
666680
{
667681
if (heap_tuple_needs_eventual_freeze(tuple.t_data))
668-
record_corrupt_item(items, &tuple.t_data->t_ctid);
682+
record_corrupt_item(items, &tuple.t_self);
669683
}
670684
}
671685

contrib/test_decoding/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ submake-test_decoding:
3838
$(MAKE) -C $(top_builddir)/contrib/test_decoding
3939

4040
REGRESSCHECKS=ddl xact rewrite toast permissions decoding_in_xact \
41-
decoding_into_rel binary prepared replorigin time messages
41+
decoding_into_rel binary prepared replorigin time messages \
42+
spill
4243

4344
regresscheck: | submake-regress submake-test_decoding temp-install
4445
$(MKDIR_P) regression_output

contrib/test_decoding/expected/spill.out

Lines changed: 256 additions & 0 deletions
Large diffs are not rendered by default.

contrib/test_decoding/sql/spill.sql

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
-- predictability
2+
SET synchronous_commit = on;
3+
4+
SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding');
5+
6+
CREATE TABLE spill_test(data text);
7+
8+
-- consume DDL
9+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
10+
11+
-- spilling main xact
12+
BEGIN;
13+
INSERT INTO spill_test SELECT 'serialize-topbig--1:'||g.i FROM generate_series(1, 5000) g(i);
14+
COMMIT;
15+
SELECT (regexp_split_to_array(data, ':'))[4], COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)]
16+
FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT'
17+
GROUP BY 1 ORDER BY 1;
18+
19+
-- spilling subxact, nothing in main
20+
BEGIN;
21+
SAVEPOINT s;
22+
INSERT INTO spill_test SELECT 'serialize-subbig--1:'||g.i FROM generate_series(1, 5000) g(i);
23+
RELEASE SAVEPOINT s;
24+
COMMIT;
25+
SELECT (regexp_split_to_array(data, ':'))[4], COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)]
26+
FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT'
27+
GROUP BY 1 ORDER BY 1;
28+
29+
-- spilling subxact, spilling main xact
30+
BEGIN;
31+
SAVEPOINT s;
32+
INSERT INTO spill_test SELECT 'serialize-subbig-topbig--1:'||g.i FROM generate_series(1, 5000) g(i);
33+
RELEASE SAVEPOINT s;
34+
INSERT INTO spill_test SELECT 'serialize-subbig-topbig--2:'||g.i FROM generate_series(5001, 10000) g(i);
35+
COMMIT;
36+
SELECT (regexp_split_to_array(data, ':'))[4], COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)]
37+
FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT'
38+
GROUP BY 1 ORDER BY 1;
39+
40+
-- spilling subxact, non-spilling main xact
41+
BEGIN;
42+
SAVEPOINT s;
43+
INSERT INTO spill_test SELECT 'serialize-subbig-topsmall--1:'||g.i FROM generate_series(1, 5000) g(i);
44+
RELEASE SAVEPOINT s;
45+
INSERT INTO spill_test SELECT 'serialize-subbig-topsmall--2:'||g.i FROM generate_series(5001, 5001) g(i);
46+
COMMIT;
47+
SELECT (regexp_split_to_array(data, ':'))[4], COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)]
48+
FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT'
49+
GROUP BY 1 ORDER BY 1;
50+
51+
-- not-spilling subxact, spilling main xact
52+
BEGIN;
53+
SAVEPOINT s;
54+
INSERT INTO spill_test SELECT 'serialize-subbig-topbig--1:'||g.i FROM generate_series(1, 5000) g(i);
55+
RELEASE SAVEPOINT s;
56+
INSERT INTO spill_test SELECT 'serialize-subbig-topbig--2:'||g.i FROM generate_series(5001, 10000) g(i);
57+
COMMIT;
58+
SELECT (regexp_split_to_array(data, ':'))[4], COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)]
59+
FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT'
60+
GROUP BY 1 ORDER BY 1;
61+
62+
-- spilling main xact, spilling subxact
63+
BEGIN;
64+
INSERT INTO spill_test SELECT 'serialize-topbig-subbig--1:'||g.i FROM generate_series(1, 5000) g(i);
65+
SAVEPOINT s;
66+
INSERT INTO spill_test SELECT 'serialize-topbig-subbig--2:'||g.i FROM generate_series(5001, 10000) g(i);
67+
RELEASE SAVEPOINT s;
68+
COMMIT;
69+
SELECT (regexp_split_to_array(data, ':'))[4], COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)]
70+
FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT'
71+
GROUP BY 1 ORDER BY 1;
72+
73+
-- spilling main xact, not spilling subxact
74+
BEGIN;
75+
INSERT INTO spill_test SELECT 'serialize-topbig-subsmall--1:'||g.i FROM generate_series(1, 5000) g(i);
76+
SAVEPOINT s;
77+
INSERT INTO spill_test SELECT 'serialize-topbig-subsmall--2:'||g.i FROM generate_series(5001, 5001) g(i);
78+
RELEASE SAVEPOINT s;
79+
COMMIT;
80+
SELECT (regexp_split_to_array(data, ':'))[4], COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)]
81+
FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT'
82+
GROUP BY 1 ORDER BY 1;
83+
84+
-- spilling subxact, followed by another spilling subxact
85+
BEGIN;
86+
SAVEPOINT s1;
87+
INSERT INTO spill_test SELECT 'serialize-subbig-subbig--1:'||g.i FROM generate_series(1, 5000) g(i);
88+
RELEASE SAVEPOINT s1;
89+
SAVEPOINT s2;
90+
INSERT INTO spill_test SELECT 'serialize-subbig-subbig--2:'||g.i FROM generate_series(5001, 10000) g(i);
91+
RELEASE SAVEPOINT s2;
92+
COMMIT;
93+
SELECT (regexp_split_to_array(data, ':'))[4], COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)]
94+
FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT'
95+
GROUP BY 1 ORDER BY 1;
96+
97+
-- spilling subxact, followed by not spilling subxact
98+
BEGIN;
99+
SAVEPOINT s1;
100+
INSERT INTO spill_test SELECT 'serialize-subbig-subsmall--1:'||g.i FROM generate_series(1, 5000) g(i);
101+
RELEASE SAVEPOINT s1;
102+
SAVEPOINT s2;
103+
INSERT INTO spill_test SELECT 'serialize-subbig-subsmall--2:'||g.i FROM generate_series(5001, 5001) g(i);
104+
RELEASE SAVEPOINT s2;
105+
COMMIT;
106+
SELECT (regexp_split_to_array(data, ':'))[4], COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)]
107+
FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT'
108+
GROUP BY 1 ORDER BY 1;
109+
110+
-- not spilling subxact, followed by spilling subxact
111+
BEGIN;
112+
SAVEPOINT s1;
113+
INSERT INTO spill_test SELECT 'serialize-subsmall-subbig--1:'||g.i FROM generate_series(1, 1) g(i);
114+
RELEASE SAVEPOINT s1;
115+
SAVEPOINT s2;
116+
INSERT INTO spill_test SELECT 'serialize-subsmall-subbig--2:'||g.i FROM generate_series(2, 5001) g(i);
117+
RELEASE SAVEPOINT s2;
118+
COMMIT;
119+
SELECT (regexp_split_to_array(data, ':'))[4], COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)]
120+
FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT'
121+
GROUP BY 1 ORDER BY 1;
122+
123+
-- spilling subxact, containing another spilling subxact
124+
BEGIN;
125+
SAVEPOINT s1;
126+
INSERT INTO spill_test SELECT 'serialize-nested-subbig-subbig--1:'||g.i FROM generate_series(1, 5000) g(i);
127+
SAVEPOINT s2;
128+
INSERT INTO spill_test SELECT 'serialize-nested-subbig-subbig--2:'||g.i FROM generate_series(5001, 10000) g(i);
129+
RELEASE SAVEPOINT s2;
130+
RELEASE SAVEPOINT s1;
131+
COMMIT;
132+
SELECT (regexp_split_to_array(data, ':'))[4], COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)]
133+
FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT'
134+
GROUP BY 1 ORDER BY 1;
135+
136+
-- spilling subxact, containing a not spilling subxact
137+
BEGIN;
138+
SAVEPOINT s1;
139+
INSERT INTO spill_test SELECT 'serialize-nested-subbig-subsmall--1:'||g.i FROM generate_series(1, 5000) g(i);
140+
SAVEPOINT s2;
141+
INSERT INTO spill_test SELECT 'serialize-nested-subbig-subsmall--2:'||g.i FROM generate_series(5001, 5001) g(i);
142+
RELEASE SAVEPOINT s2;
143+
RELEASE SAVEPOINT s1;
144+
COMMIT;
145+
SELECT (regexp_split_to_array(data, ':'))[4], COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)]
146+
FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT'
147+
GROUP BY 1 ORDER BY 1;
148+
149+
-- not spilling subxact, containing a spilling subxact
150+
BEGIN;
151+
SAVEPOINT s1;
152+
INSERT INTO spill_test SELECT 'serialize-nested-subsmall-subbig--1:'||g.i FROM generate_series(1, 1) g(i);
153+
SAVEPOINT s2;
154+
INSERT INTO spill_test SELECT 'serialize-nested-subsmall-subbig--2:'||g.i FROM generate_series(2, 5001) g(i);
155+
RELEASE SAVEPOINT s2;
156+
RELEASE SAVEPOINT s1;
157+
COMMIT;
158+
SELECT (regexp_split_to_array(data, ':'))[4], COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)]
159+
FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT'
160+
GROUP BY 1 ORDER BY 1;
161+
162+
-- not spilling subxact, containing a spilling subxact that aborts and one that commits
163+
BEGIN;
164+
SAVEPOINT s1;
165+
INSERT INTO spill_test SELECT 'serialize-nested-subbig-subbigabort--1:'||g.i FROM generate_series(1, 5000) g(i);
166+
SAVEPOINT s2;
167+
INSERT INTO spill_test SELECT 'serialize-nested-subbig-subbigabort--2:'||g.i FROM generate_series(5001, 10000) g(i);
168+
ROLLBACK TO SAVEPOINT s2;
169+
SAVEPOINT s3;
170+
INSERT INTO spill_test SELECT 'serialize-nested-subbig-subbigabort-subbig-3:'||g.i FROM generate_series(5001, 10000) g(i);
171+
RELEASE SAVEPOINT s1;
172+
COMMIT;
173+
SELECT (regexp_split_to_array(data, ':'))[4], COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)]
174+
FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT'
175+
GROUP BY 1 ORDER BY 1;
176+
177+
DROP TABLE spill_test;
178+
179+
SELECT pg_drop_replication_slot('regression_slot');

doc/src/sgml/client-auth.sgml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,7 @@ local db1,db2,@demodbs all md5
711711
<para>
712712
When using an external authentication system such as Ident or GSSAPI,
713713
the name of the operating system user that initiated the connection
714-
might not be the same as the database user that is to be connect as.
714+
might not be the same as the database user (role) that is to be used.
715715
In this case, a user name map can be applied to map the operating system
716716
user name to a database user. To use user name mapping, specify
717717
<literal>map</literal>=<replaceable>map-name</replaceable>

doc/src/sgml/installation.sgml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,7 +1422,7 @@ su - postgres
14221422
<term><envar>PERL</envar></term>
14231423
<listitem>
14241424
<para>
1425-
Full path to the Perl interpreter. This will be used to
1425+
Full path name of the Perl interpreter. This will be used to
14261426
determine the dependencies for building PL/Perl.
14271427
</para>
14281428
</listitem>
@@ -1432,7 +1432,7 @@ su - postgres
14321432
<term><envar>PYTHON</envar></term>
14331433
<listitem>
14341434
<para>
1435-
Full path to the Python interpreter. This will be used to
1435+
Full path name of the Python interpreter. This will be used to
14361436
determine the dependencies for building PL/Python. Also,
14371437
whether Python 2 or 3 is specified here (or otherwise
14381438
implicitly chosen) determines which variant of the PL/Python
@@ -1449,7 +1449,7 @@ su - postgres
14491449
<term><envar>TCLSH</envar></term>
14501450
<listitem>
14511451
<para>
1452-
Full path to the Tcl interpreter. This will be used to
1452+
Full path name of the Tcl interpreter. This will be used to
14531453
determine the dependencies for building PL/Tcl, and it will
14541454
be substituted into Tcl scripts.
14551455
</para>

doc/src/sgml/parallel.sgml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
189189
Even when parallel query plan is generated for a particular query, there
190190
are several circumstances under which it will be impossible to execute
191191
that plan in parallel at execution time. If this occurs, the leader
192-
will execute the portion of the plan between below the <literal>Gather</>
192+
will execute the portion of the plan below the <literal>Gather</>
193193
node entirely by itself, almost as if the <literal>Gather</> node were
194194
not present. This will happen if any of the following conditions are met:
195195
</para>
@@ -241,7 +241,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
241241
than normal but would produce incorrect results. Instead, the parallel
242242
portion of the plan must be what is known internally to the query
243243
optimizer as a <firstterm>partial plan</>; that is, it must constructed
244-
so that each process will which executes the plan will generate only a
244+
so that each process which executes the plan will generate only a
245245
subset of the output rows in such a way that each required output row
246246
is guaranteed to be generated by exactly one of the cooperating processes.
247247
</para>
@@ -339,7 +339,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
339339

340340
<para>
341341
When executing a parallel plan, you can use <literal>EXPLAIN (ANALYZE,
342-
VERBOSE)</literal> will display per-worker statistics for each plan node.
342+
VERBOSE)</literal> to display per-worker statistics for each plan node.
343343
This may be useful in determining whether the work is being evenly
344344
distributed between all plan nodes and more generally in understanding the
345345
performance characteristics of the plan.

0 commit comments

Comments
 (0)