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

Commit9ccc049

Browse files
committed
pg_buffercache: Add pg_buffercache_mark_dirty{,_relation,_all}()
This commit introduces three new functions for marking shared buffers asdirty by using the functions introduced in9660906:* pg_buffercache_mark_dirty() for one shared buffer.- pg_buffercache_mark_dirt_relation() for all the shared buffers in arelation.* pg_buffercache_mark_dirty_all() for all the shared buffers in pool.The "_all" and "_relation" flavors are designed to address theinefficiency of repeatedly calling pg_buffercache_mark_dirty() for eachindividual buffer, which can be time-consuming when dealing with withlarge shared buffers pool.These functions are intended as developer tools and are available onlyto superusers. There is no need to bump the version of pg_buffercache,4b203d4 having done this job in this release cycle.Author: Nazir Bilal Yavuz <byavuz81@gmail.com>Reviewed-by: Andres Freund <andres@anarazel.de>Reviewed-by: Aidar Imamov <a.imamov@postgrespro.ru>Reviewed-by: Amit Kapila <amit.kapila16@gmail.com>Reviewed-by: Joseph Koshakow <koshy44@gmail.com>Reviewed-by: Michael Paquier <michael@paquier.xyz>Reviewed-by: Yuhang Qiu <iamqyh@gmail.com>Reviewed-by: Xuneng Zhou <xunengzhou@gmail.com>Discussion:https://postgr.es/m/CAN55FZ0h_YoSqqutxV6DES1RW8ig6wcA8CR9rJk358YRMxZFmw@mail.gmail.com
1 parentd167c19 commit9ccc049

File tree

5 files changed

+296
-8
lines changed

5 files changed

+296
-8
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 EXECUTEON FUNCTION pg_buffercache_os_pages(boolean) TO pg_monitor;
3232
GRANTSELECTON pg_buffercache_os_pages TO pg_monitor;
3333
GRANTSELECTON pg_buffercache_numa TO pg_monitor;
34+
35+
-- Functions to mark buffers as dirty.
36+
CREATEFUNCTIONpg_buffercache_mark_dirty(
37+
INint,
38+
OUT buffer_dirtiedboolean,
39+
OUT buffer_already_dirtyboolean)
40+
AS'MODULE_PATHNAME','pg_buffercache_mark_dirty'
41+
LANGUAGE C PARALLEL SAFE VOLATILE STRICT;
42+
43+
CREATEFUNCTIONpg_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+
CREATEFUNCTIONpg_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
#defineNUM_BUFFERCACHE_EVICT_ELEM 2
2626
#defineNUM_BUFFERCACHE_EVICT_RELATION_ELEM 3
2727
#defineNUM_BUFFERCACHE_EVICT_ALL_ELEM 3
28+
#defineNUM_BUFFERCACHE_MARK_DIRTY_ELEM 2
29+
#defineNUM_BUFFERCACHE_MARK_DIRTY_RELATION_ELEM 3
30+
#defineNUM_BUFFERCACHE_MARK_DIRTY_ALL_ELEM 3
2831

2932
#defineNUM_BUFFERCACHE_OS_PAGES_ELEM3
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+
Datumresult;
844+
TupleDesctupledesc;
845+
HeapTupletuple;
846+
Datumvalues[NUM_BUFFERCACHE_MARK_DIRTY_ELEM];
847+
boolnulls[NUM_BUFFERCACHE_MARK_DIRTY_ELEM]= {0};
848+
849+
Bufferbuf=PG_GETARG_INT32(0);
850+
boolbuffer_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+
Datumresult;
876+
TupleDesctupledesc;
877+
HeapTupletuple;
878+
Datumvalues[NUM_BUFFERCACHE_MARK_DIRTY_RELATION_ELEM];
879+
boolnulls[NUM_BUFFERCACHE_MARK_DIRTY_RELATION_ELEM]= {0};
880+
881+
OidrelOid;
882+
Relationrel;
883+
884+
int32buffers_already_dirty=0;
885+
int32buffers_dirtied=0;
886+
int32buffers_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+
Datumresult;
925+
TupleDesctupledesc;
926+
HeapTupletuple;
927+
Datumvalues[NUM_BUFFERCACHE_MARK_DIRTY_ALL_ELEM];
928+
boolnulls[NUM_BUFFERCACHE_MARK_DIRTY_ALL_ELEM]= {0};
929+
930+
int32buffers_already_dirty=0;
931+
int32buffers_dirtied=0;
932+
int32buffers_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
SELECT2147483647 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
DROPTABLE temp_pg_buffercache;
7078

7179
-- These shouldn't fail
7280
SELECT buffer_evictedIS NOT NULLFROM pg_buffercache_evict(1);
7381
SELECT buffers_evictedIS NOT NULLFROM pg_buffercache_evict_all();
7482
CREATETABLEshared_pg_buffercache();
7583
SELECT buffers_evictedIS NOT NULLFROM pg_buffercache_evict_relation('shared_pg_buffercache');
84+
SELECT buffers_dirtiedIS NOT NULLFROM pg_buffercache_mark_dirty_relation('shared_pg_buffercache');
7685
DROPTABLE 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;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp