🌐 AI搜索 & 代理 主页
Skip to content

Commit cf77e0f

Browse files
authored
Merge branch 'postgres:master' into master
2 parents 4988108 + 87c6f8b commit cf77e0f

File tree

72 files changed

+2075
-276
lines changed

Some content is hidden

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

72 files changed

+2075
-276
lines changed

contrib/pg_buffercache/expected/pg_buffercache.out

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ SELECT count(*) > 0 FROM pg_buffercache_usage_counts();
7575

7676
RESET role;
7777
------
78-
---- Test pg_buffercache_evict* functions
78+
---- Test pg_buffercache_evict* and pg_buffercache_mark_dirty* functions
7979
------
8080
CREATE ROLE regress_buffercache_normal;
8181
SET ROLE regress_buffercache_normal;
@@ -86,6 +86,12 @@ SELECT * FROM pg_buffercache_evict_relation(1);
8686
ERROR: must be superuser to use pg_buffercache_evict_relation()
8787
SELECT * FROM pg_buffercache_evict_all();
8888
ERROR: must be superuser to use pg_buffercache_evict_all()
89+
SELECT * FROM pg_buffercache_mark_dirty(1);
90+
ERROR: must be superuser to use pg_buffercache_mark_dirty()
91+
SELECT * FROM pg_buffercache_mark_dirty_relation(1);
92+
ERROR: must be superuser to use pg_buffercache_mark_dirty_relation()
93+
SELECT * FROM pg_buffercache_mark_dirty_all();
94+
ERROR: must be superuser to use pg_buffercache_mark_dirty_all()
8995
RESET ROLE;
9096
-- These should return nothing, because these are STRICT functions
9197
SELECT * FROM pg_buffercache_evict(NULL);
@@ -100,6 +106,18 @@ SELECT * FROM pg_buffercache_evict_relation(NULL);
100106
| |
101107
(1 row)
102108

109+
SELECT * FROM pg_buffercache_mark_dirty(NULL);
110+
buffer_dirtied | buffer_already_dirty
111+
----------------+----------------------
112+
|
113+
(1 row)
114+
115+
SELECT * FROM pg_buffercache_mark_dirty_relation(NULL);
116+
buffers_dirtied | buffers_already_dirty | buffers_skipped
117+
-----------------+-----------------------+-----------------
118+
| |
119+
(1 row)
120+
103121
-- These should fail because they are not called by valid range of buffers
104122
-- Number of the shared buffers are limited by max integer
105123
SELECT 2147483647 max_buffers \gset
@@ -109,11 +127,18 @@ SELECT * FROM pg_buffercache_evict(0);
109127
ERROR: bad buffer ID: 0
110128
SELECT * FROM pg_buffercache_evict(:max_buffers);
111129
ERROR: bad buffer ID: 2147483647
112-
-- This should fail because pg_buffercache_evict_relation() doesn't accept
113-
-- local relations
130+
SELECT * FROM pg_buffercache_mark_dirty(-1);
131+
ERROR: bad buffer ID: -1
132+
SELECT * FROM pg_buffercache_mark_dirty(0);
133+
ERROR: bad buffer ID: 0
134+
SELECT * FROM pg_buffercache_mark_dirty(:max_buffers);
135+
ERROR: bad buffer ID: 2147483647
136+
-- These should fail because they don't accept local relations
114137
CREATE TEMP TABLE temp_pg_buffercache();
115138
SELECT * FROM pg_buffercache_evict_relation('temp_pg_buffercache');
116139
ERROR: relation uses local buffers, pg_buffercache_evict_relation() is intended to be used for shared buffers only
140+
SELECT * FROM pg_buffercache_mark_dirty_relation('temp_pg_buffercache');
141+
ERROR: relation uses local buffers, pg_buffercache_mark_dirty_relation() is intended to be used for shared buffers only
117142
DROP TABLE temp_pg_buffercache;
118143
-- These shouldn't fail
119144
SELECT buffer_evicted IS NOT NULL FROM pg_buffercache_evict(1);
@@ -135,5 +160,23 @@ SELECT buffers_evicted IS NOT NULL FROM pg_buffercache_evict_relation('shared_pg
135160
t
136161
(1 row)
137162

163+
SELECT buffers_dirtied IS NOT NULL FROM pg_buffercache_mark_dirty_relation('shared_pg_buffercache');
164+
?column?
165+
----------
166+
t
167+
(1 row)
168+
138169
DROP TABLE shared_pg_buffercache;
170+
SELECT pg_buffercache_mark_dirty(1) IS NOT NULL;
171+
?column?
172+
----------
173+
t
174+
(1 row)
175+
176+
SELECT pg_buffercache_mark_dirty_all() IS NOT NULL;
177+
?column?
178+
----------
179+
t
180+
(1 row)
181+
139182
DROP ROLE regress_buffercache_normal;

contrib/pg_buffercache/pg_buffercache--1.6--1.7.sql

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,26 @@ REVOKE ALL ON pg_buffercache_numa FROM PUBLIC;
3131
GRANT EXECUTE ON FUNCTION pg_buffercache_os_pages(boolean) TO pg_monitor;
3232
GRANT SELECT ON pg_buffercache_os_pages TO pg_monitor;
3333
GRANT SELECT ON pg_buffercache_numa TO pg_monitor;
34+
35+
-- Functions to mark buffers as dirty.
36+
CREATE FUNCTION pg_buffercache_mark_dirty(
37+
IN int,
38+
OUT buffer_dirtied boolean,
39+
OUT buffer_already_dirty boolean)
40+
AS 'MODULE_PATHNAME', 'pg_buffercache_mark_dirty'
41+
LANGUAGE C PARALLEL SAFE VOLATILE STRICT;
42+
43+
CREATE FUNCTION pg_buffercache_mark_dirty_relation(
44+
IN regclass,
45+
OUT buffers_dirtied int4,
46+
OUT buffers_already_dirty int4,
47+
OUT buffers_skipped int4)
48+
AS 'MODULE_PATHNAME', 'pg_buffercache_mark_dirty_relation'
49+
LANGUAGE C PARALLEL SAFE VOLATILE STRICT;
50+
51+
CREATE FUNCTION pg_buffercache_mark_dirty_all(
52+
OUT buffers_dirtied int4,
53+
OUT buffers_already_dirty int4,
54+
OUT buffers_skipped int4)
55+
AS 'MODULE_PATHNAME', 'pg_buffercache_mark_dirty_all'
56+
LANGUAGE C PARALLEL SAFE VOLATILE;

contrib/pg_buffercache/pg_buffercache_pages.c

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
#define NUM_BUFFERCACHE_EVICT_ELEM 2
2626
#define NUM_BUFFERCACHE_EVICT_RELATION_ELEM 3
2727
#define NUM_BUFFERCACHE_EVICT_ALL_ELEM 3
28+
#define NUM_BUFFERCACHE_MARK_DIRTY_ELEM 2
29+
#define NUM_BUFFERCACHE_MARK_DIRTY_RELATION_ELEM 3
30+
#define NUM_BUFFERCACHE_MARK_DIRTY_ALL_ELEM 3
2831

2932
#define NUM_BUFFERCACHE_OS_PAGES_ELEM 3
3033

@@ -101,6 +104,9 @@ PG_FUNCTION_INFO_V1(pg_buffercache_usage_counts);
101104
PG_FUNCTION_INFO_V1(pg_buffercache_evict);
102105
PG_FUNCTION_INFO_V1(pg_buffercache_evict_relation);
103106
PG_FUNCTION_INFO_V1(pg_buffercache_evict_all);
107+
PG_FUNCTION_INFO_V1(pg_buffercache_mark_dirty);
108+
PG_FUNCTION_INFO_V1(pg_buffercache_mark_dirty_relation);
109+
PG_FUNCTION_INFO_V1(pg_buffercache_mark_dirty_all);
104110

105111

106112
/* Only need to touch memory once per backend process lifetime */
@@ -826,3 +832,119 @@ pg_buffercache_evict_all(PG_FUNCTION_ARGS)
826832

827833
PG_RETURN_DATUM(result);
828834
}
835+
836+
/*
837+
* Try to mark a shared buffer as dirty.
838+
*/
839+
Datum
840+
pg_buffercache_mark_dirty(PG_FUNCTION_ARGS)
841+
{
842+
843+
Datum result;
844+
TupleDesc tupledesc;
845+
HeapTuple tuple;
846+
Datum values[NUM_BUFFERCACHE_MARK_DIRTY_ELEM];
847+
bool nulls[NUM_BUFFERCACHE_MARK_DIRTY_ELEM] = {0};
848+
849+
Buffer buf = PG_GETARG_INT32(0);
850+
bool buffer_already_dirty;
851+
852+
if (get_call_result_type(fcinfo, NULL, &tupledesc) != TYPEFUNC_COMPOSITE)
853+
elog(ERROR, "return type must be a row type");
854+
855+
pg_buffercache_superuser_check("pg_buffercache_mark_dirty");
856+
857+
if (buf < 1 || buf > NBuffers)
858+
elog(ERROR, "bad buffer ID: %d", buf);
859+
860+
values[0] = BoolGetDatum(MarkDirtyUnpinnedBuffer(buf, &buffer_already_dirty));
861+
values[1] = BoolGetDatum(buffer_already_dirty);
862+
863+
tuple = heap_form_tuple(tupledesc, values, nulls);
864+
result = HeapTupleGetDatum(tuple);
865+
866+
PG_RETURN_DATUM(result);
867+
}
868+
869+
/*
870+
* Try to mark all the shared buffers of a relation as dirty.
871+
*/
872+
Datum
873+
pg_buffercache_mark_dirty_relation(PG_FUNCTION_ARGS)
874+
{
875+
Datum result;
876+
TupleDesc tupledesc;
877+
HeapTuple tuple;
878+
Datum values[NUM_BUFFERCACHE_MARK_DIRTY_RELATION_ELEM];
879+
bool nulls[NUM_BUFFERCACHE_MARK_DIRTY_RELATION_ELEM] = {0};
880+
881+
Oid relOid;
882+
Relation rel;
883+
884+
int32 buffers_already_dirty = 0;
885+
int32 buffers_dirtied = 0;
886+
int32 buffers_skipped = 0;
887+
888+
if (get_call_result_type(fcinfo, NULL, &tupledesc) != TYPEFUNC_COMPOSITE)
889+
elog(ERROR, "return type must be a row type");
890+
891+
pg_buffercache_superuser_check("pg_buffercache_mark_dirty_relation");
892+
893+
relOid = PG_GETARG_OID(0);
894+
895+
rel = relation_open(relOid, AccessShareLock);
896+
897+
if (RelationUsesLocalBuffers(rel))
898+
ereport(ERROR,
899+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
900+
errmsg("relation uses local buffers, %s() is intended to be used for shared buffers only",
901+
"pg_buffercache_mark_dirty_relation")));
902+
903+
MarkDirtyRelUnpinnedBuffers(rel, &buffers_dirtied, &buffers_already_dirty,
904+
&buffers_skipped);
905+
906+
relation_close(rel, AccessShareLock);
907+
908+
values[0] = Int32GetDatum(buffers_dirtied);
909+
values[1] = Int32GetDatum(buffers_already_dirty);
910+
values[2] = Int32GetDatum(buffers_skipped);
911+
912+
tuple = heap_form_tuple(tupledesc, values, nulls);
913+
result = HeapTupleGetDatum(tuple);
914+
915+
PG_RETURN_DATUM(result);
916+
}
917+
918+
/*
919+
* Try to mark all the shared buffers as dirty.
920+
*/
921+
Datum
922+
pg_buffercache_mark_dirty_all(PG_FUNCTION_ARGS)
923+
{
924+
Datum result;
925+
TupleDesc tupledesc;
926+
HeapTuple tuple;
927+
Datum values[NUM_BUFFERCACHE_MARK_DIRTY_ALL_ELEM];
928+
bool nulls[NUM_BUFFERCACHE_MARK_DIRTY_ALL_ELEM] = {0};
929+
930+
int32 buffers_already_dirty = 0;
931+
int32 buffers_dirtied = 0;
932+
int32 buffers_skipped = 0;
933+
934+
if (get_call_result_type(fcinfo, NULL, &tupledesc) != TYPEFUNC_COMPOSITE)
935+
elog(ERROR, "return type must be a row type");
936+
937+
pg_buffercache_superuser_check("pg_buffercache_mark_dirty_all");
938+
939+
MarkDirtyAllUnpinnedBuffers(&buffers_dirtied, &buffers_already_dirty,
940+
&buffers_skipped);
941+
942+
values[0] = Int32GetDatum(buffers_dirtied);
943+
values[1] = Int32GetDatum(buffers_already_dirty);
944+
values[2] = Int32GetDatum(buffers_skipped);
945+
946+
tuple = heap_form_tuple(tupledesc, values, nulls);
947+
result = HeapTupleGetDatum(tuple);
948+
949+
PG_RETURN_DATUM(result);
950+
}

contrib/pg_buffercache/sql/pg_buffercache.sql

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ RESET role;
3838

3939

4040
------
41-
---- Test pg_buffercache_evict* functions
41+
---- Test pg_buffercache_evict* and pg_buffercache_mark_dirty* functions
4242
------
4343

4444
CREATE ROLE regress_buffercache_normal;
@@ -48,31 +48,42 @@ SET ROLE regress_buffercache_normal;
4848
SELECT * FROM pg_buffercache_evict(1);
4949
SELECT * FROM pg_buffercache_evict_relation(1);
5050
SELECT * FROM pg_buffercache_evict_all();
51+
SELECT * FROM pg_buffercache_mark_dirty(1);
52+
SELECT * FROM pg_buffercache_mark_dirty_relation(1);
53+
SELECT * FROM pg_buffercache_mark_dirty_all();
5154

5255
RESET ROLE;
5356

5457
-- These should return nothing, because these are STRICT functions
5558
SELECT * FROM pg_buffercache_evict(NULL);
5659
SELECT * FROM pg_buffercache_evict_relation(NULL);
60+
SELECT * FROM pg_buffercache_mark_dirty(NULL);
61+
SELECT * FROM pg_buffercache_mark_dirty_relation(NULL);
5762

5863
-- These should fail because they are not called by valid range of buffers
5964
-- Number of the shared buffers are limited by max integer
6065
SELECT 2147483647 max_buffers \gset
6166
SELECT * FROM pg_buffercache_evict(-1);
6267
SELECT * FROM pg_buffercache_evict(0);
6368
SELECT * FROM pg_buffercache_evict(:max_buffers);
69+
SELECT * FROM pg_buffercache_mark_dirty(-1);
70+
SELECT * FROM pg_buffercache_mark_dirty(0);
71+
SELECT * FROM pg_buffercache_mark_dirty(:max_buffers);
6472

65-
-- This should fail because pg_buffercache_evict_relation() doesn't accept
66-
-- local relations
73+
-- These should fail because they don't accept local relations
6774
CREATE TEMP TABLE temp_pg_buffercache();
6875
SELECT * FROM pg_buffercache_evict_relation('temp_pg_buffercache');
76+
SELECT * FROM pg_buffercache_mark_dirty_relation('temp_pg_buffercache');
6977
DROP TABLE temp_pg_buffercache;
7078

7179
-- These shouldn't fail
7280
SELECT buffer_evicted IS NOT NULL FROM pg_buffercache_evict(1);
7381
SELECT buffers_evicted IS NOT NULL FROM pg_buffercache_evict_all();
7482
CREATE TABLE shared_pg_buffercache();
7583
SELECT buffers_evicted IS NOT NULL FROM pg_buffercache_evict_relation('shared_pg_buffercache');
84+
SELECT buffers_dirtied IS NOT NULL FROM pg_buffercache_mark_dirty_relation('shared_pg_buffercache');
7685
DROP TABLE shared_pg_buffercache;
86+
SELECT pg_buffercache_mark_dirty(1) IS NOT NULL;
87+
SELECT pg_buffercache_mark_dirty_all() IS NOT NULL;
7788

7889
DROP ROLE regress_buffercache_normal;

contrib/postgres_fdw/expected/postgres_fdw.out

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2975,9 +2975,9 @@ select sum(t1.c1), count(t2.c1) from ft1 t1 inner join ft2 t2 on (t1.c1 = t2.c1)
29752975
QUERY PLAN
29762976
----------------------------------------------------------------------------------------------------------------------------
29772977
Aggregate
2978-
Output: sum(t1.c1), count(t2.c1)
2978+
Output: sum(t1.c1), count(*)
29792979
-> Foreign Scan
2980-
Output: t1.c1, t2.c1
2980+
Output: t1.c1
29812981
Filter: (((((t1.c1 * t2.c1) / (t1.c1 * t2.c1)))::double precision * random()) <= '1'::double precision)
29822982
Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2)
29832983
Remote SQL: SELECT r1."C 1", r2."C 1" FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r2."C 1" = r1."C 1"))))
@@ -3073,12 +3073,12 @@ select c2 * (random() <= 1)::int as c2 from ft2 group by c2 * (random() <= 1)::i
30733073
-- GROUP BY clause in various forms, cardinal, alias and constant expression
30743074
explain (verbose, costs off)
30753075
select count(c2) w, c2 x, 5 y, 7.0 z from ft1 group by 2, y, 9.0::int order by 2;
3076-
QUERY PLAN
3077-
------------------------------------------------------------------------------------------------------------
3076+
QUERY PLAN
3077+
-----------------------------------------------------------------------------------------------------------
30783078
Foreign Scan
3079-
Output: (count(c2)), c2, 5, 7.0, 9
3079+
Output: (count(*)), c2, 5, 7.0, 9
30803080
Relations: Aggregate on (public.ft1)
3081-
Remote SQL: SELECT count(c2), c2, 5, 7.0, 9 FROM "S 1"."T 1" GROUP BY 2, 3, 5 ORDER BY c2 ASC NULLS LAST
3081+
Remote SQL: SELECT count(*), c2, 5, 7.0, 9 FROM "S 1"."T 1" GROUP BY 2, 3, 5 ORDER BY c2 ASC NULLS LAST
30823082
(4 rows)
30833083

30843084
select count(c2) w, c2 x, 5 y, 7.0 z from ft1 group by 2, y, 9.0::int order by 2;
@@ -3379,8 +3379,8 @@ select distinct (select count(*) filter (where t2.c2 = 6 and t2.c1 < 10) from ft
33793379
-- Inner query is aggregation query
33803380
explain (verbose, costs off)
33813381
select distinct (select count(t1.c1) filter (where t2.c2 = 6 and t2.c1 < 10) from ft1 t1 where t1.c1 = 6) from ft2 t2 where t2.c2 % 6 = 0 order by 1;
3382-
QUERY PLAN
3383-
------------------------------------------------------------------------------------------------------------------------------------------------------
3382+
QUERY PLAN
3383+
--------------------------------------------------------------------------------------------------------------------------------------------------
33843384
Unique
33853385
Output: ((SubPlan expr_1))
33863386
-> Sort
@@ -3391,9 +3391,9 @@ select distinct (select count(t1.c1) filter (where t2.c2 = 6 and t2.c1 < 10) fro
33913391
Remote SQL: SELECT "C 1", c2 FROM "S 1"."T 1" WHERE (((c2 % 6) = 0))
33923392
SubPlan expr_1
33933393
-> Foreign Scan
3394-
Output: (count(t1.c1) FILTER (WHERE ((t2.c2 = 6) AND (t2.c1 < 10))))
3394+
Output: (count(*) FILTER (WHERE ((t2.c2 = 6) AND (t2.c1 < 10))))
33953395
Relations: Aggregate on (public.ft1 t1)
3396-
Remote SQL: SELECT count("C 1") FILTER (WHERE (($1::integer = 6) AND ($2::integer < 10))) FROM "S 1"."T 1" WHERE (("C 1" = 6))
3396+
Remote SQL: SELECT count(*) FILTER (WHERE (($1::integer = 6) AND ($2::integer < 10))) FROM "S 1"."T 1" WHERE (("C 1" = 6))
33973397
(13 rows)
33983398

33993399
select distinct (select count(t1.c1) filter (where t2.c2 = 6 and t2.c1 < 10) from ft1 t1 where t1.c1 = 6) from ft2 t2 where t2.c2 % 6 = 0 order by 1;

doc/src/sgml/monitoring.sgml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1665,7 +1665,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage
16651665
</para>
16661666
<para>
16671667
Number of times the slot synchronization is skipped. Slot
1668-
synchronization occur only on standby servers and thus this column has
1668+
synchronization occurs only on standby servers and thus this column has
16691669
no meaning on the primary server.
16701670
</para>
16711671
</entry>
@@ -1677,7 +1677,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage
16771677
</para>
16781678
<para>
16791679
Time at which last slot synchronization was skipped. Slot
1680-
synchronization occur only on standby servers and thus this column has
1680+
synchronization occurs only on standby servers and thus this column has
16811681
no meaning on the primary server.
16821682
</para>
16831683
</entry>

doc/src/sgml/parallel.sgml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,15 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
299299
within each worker process.
300300
</para>
301301
</listitem>
302+
<listitem>
303+
<para>
304+
In a <emphasis>parallel tid range scan</emphasis>, the range of blocks
305+
will be subdivided into smaller ranges which are shared among the
306+
cooperating processes. Each worker process will complete the scanning
307+
of its given range of blocks before requesting an additional range of
308+
blocks.
309+
</para>
310+
</listitem>
302311
</itemizedlist>
303312

304313
Other scan types, such as scans of non-btree indexes, may support

0 commit comments

Comments
 (0)