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

Commitc32afe5

Browse files
committed
pg_prewarm, a contrib module for prewarming relationd data.
Patch by me. Review by Álvaro Herrera, Amit Kapila, Jeff Janes,Gurjeet Singh, and others.
1 parent6eda3e9 commitc32afe5

File tree

9 files changed

+314
-0
lines changed

9 files changed

+314
-0
lines changed

‎contrib/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ SUBDIRS = \
3232
pg_archivecleanup\
3333
pg_buffercache\
3434
pg_freespacemap\
35+
pg_prewarm\
3536
pg_standby\
3637
pg_stat_statements\
3738
pg_test_fsync\

‎contrib/pg_prewarm/Makefile

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# contrib/pg_prewarm/Makefile
2+
3+
MODULE_big = pg_prewarm
4+
OBJS = pg_prewarm.o
5+
6+
EXTENSION = pg_prewarm
7+
DATA = pg_prewarm--1.0.sql
8+
9+
ifdefUSE_PGXS
10+
PG_CONFIG = pg_config
11+
PGXS :=$(shell$(PG_CONFIG) --pgxs)
12+
include$(PGXS)
13+
else
14+
subdir = contrib/pg_prewarm
15+
top_builddir = ../..
16+
include$(top_builddir)/src/Makefile.global
17+
include$(top_srcdir)/contrib/contrib-global.mk
18+
endif
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/* contrib/pg_prewarm/pg_prewarm--1.0.sql*/
2+
3+
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
4+
\echo Use"CREATE EXTENSION pg_prewarm" to load this file. \quit
5+
6+
-- Register the function.
7+
CREATEFUNCTIONpg_prewarm(regclass,
8+
modetext default'buffer',
9+
forktext default'main',
10+
first_block int8 defaultnull,
11+
last_block int8 defaultnull)
12+
RETURNS int8
13+
AS'MODULE_PATHNAME','pg_prewarm'
14+
LANGUAGE C;

‎contrib/pg_prewarm/pg_prewarm.c

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* pg_prewarm.c
4+
* prewarming utilities
5+
*
6+
* Copyright (c) 2010-2013, PostgreSQL Global Development Group
7+
*
8+
* IDENTIFICATION
9+
* contrib/pg_prewarm/pg_prewarm.c
10+
*
11+
*-------------------------------------------------------------------------
12+
*/
13+
#include"postgres.h"
14+
15+
#include<sys/stat.h>
16+
#include<unistd.h>
17+
18+
#include"access/heapam.h"
19+
#include"catalog/catalog.h"
20+
#include"fmgr.h"
21+
#include"miscadmin.h"
22+
#include"storage/bufmgr.h"
23+
#include"storage/smgr.h"
24+
#include"utils/acl.h"
25+
#include"utils/builtins.h"
26+
#include"utils/lsyscache.h"
27+
#include"utils/rel.h"
28+
29+
PG_MODULE_MAGIC;
30+
31+
externDatumpg_prewarm(PG_FUNCTION_ARGS);
32+
33+
PG_FUNCTION_INFO_V1(pg_prewarm);
34+
35+
typedefenum
36+
{
37+
PREWARM_PREFETCH,
38+
PREWARM_READ,
39+
PREWARM_BUFFER
40+
}PrewarmType;
41+
42+
staticcharblockbuffer[BLCKSZ];
43+
44+
/*
45+
* pg_prewarm(regclass, mode text, fork text,
46+
* first_block int8, last_block int8)
47+
*
48+
* The first argument is the relation to be prewarmed; the second controls
49+
* how prewarming is done; legal options are 'prefetch', 'read', and 'buffer'.
50+
* The third is the name of the relation fork to be prewarmed.The fourth
51+
* and fifth arguments specify the first and last block to be prewarmed.
52+
* If the fourth argument is NULL, it will be taken as 0; if the fifth argument
53+
* is NULL, it will be taken as the number of blocks in the relation. The
54+
* return value is the number of blocks successfully prewarmed.
55+
*/
56+
Datum
57+
pg_prewarm(PG_FUNCTION_ARGS)
58+
{
59+
OidrelOid;
60+
text*forkName;
61+
text*type;
62+
int64first_block;
63+
int64last_block;
64+
int64nblocks;
65+
int64blocks_done=0;
66+
int64block;
67+
Relationrel;
68+
ForkNumberforkNumber;
69+
char*forkString;
70+
char*ttype;
71+
PrewarmTypeptype;
72+
AclResultaclresult;
73+
74+
/* Basic sanity checking. */
75+
if (PG_ARGISNULL(0))
76+
ereport(ERROR,
77+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
78+
errmsg("relation cannot be null")));
79+
relOid=PG_GETARG_OID(0);
80+
if (PG_ARGISNULL(1))
81+
ereport(ERROR,
82+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
83+
(errmsg("prewarm type cannot be null"))));
84+
type=PG_GETARG_TEXT_P(1);
85+
ttype=text_to_cstring(type);
86+
if (strcmp(ttype,"prefetch")==0)
87+
ptype=PREWARM_PREFETCH;
88+
elseif (strcmp(ttype,"read")==0)
89+
ptype=PREWARM_READ;
90+
elseif (strcmp(ttype,"buffer")==0)
91+
ptype=PREWARM_BUFFER;
92+
else
93+
{
94+
ereport(ERROR,
95+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
96+
errmsg("invalid prewarm type"),
97+
errhint("Valid prewarm types are \"prefetch\", \"read\", and \"buffer\".")));
98+
PG_RETURN_INT64(0);/* Placate compiler. */
99+
}
100+
if (PG_ARGISNULL(2))
101+
ereport(ERROR,
102+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
103+
(errmsg("relation fork cannot be null"))));
104+
forkName=PG_GETARG_TEXT_P(2);
105+
forkString=text_to_cstring(forkName);
106+
forkNumber=forkname_to_number(forkString);
107+
108+
/* Open relation and check privileges. */
109+
rel=relation_open(relOid,AccessShareLock);
110+
aclresult=pg_class_aclcheck(relOid,GetUserId(),ACL_SELECT);
111+
if (aclresult!=ACLCHECK_OK)
112+
aclcheck_error(aclresult,ACL_KIND_CLASS,get_rel_name(relOid));
113+
114+
/* Check that the fork exists. */
115+
RelationOpenSmgr(rel);
116+
if (!smgrexists(rel->rd_smgr,forkNumber))
117+
ereport(ERROR,
118+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
119+
errmsg("fork \"%s\" does not exist for this relation",
120+
forkString)));
121+
122+
/* Validate block numbers, or handle nulls. */
123+
nblocks=RelationGetNumberOfBlocksInFork(rel,forkNumber);
124+
if (PG_ARGISNULL(3))
125+
first_block=0;
126+
else
127+
{
128+
first_block=PG_GETARG_INT64(3);
129+
if (first_block<0||first_block >=nblocks)
130+
ereport(ERROR,
131+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
132+
errmsg("starting block number must be between 0 and "INT64_FORMAT,
133+
nblocks-1)));
134+
}
135+
if (PG_ARGISNULL(4))
136+
last_block=nblocks-1;
137+
else
138+
{
139+
last_block=PG_GETARG_INT64(4);
140+
if (last_block<0||last_block >=nblocks)
141+
ereport(ERROR,
142+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
143+
errmsg("ending block number must be between 0 and "INT64_FORMAT,
144+
nblocks-1)));
145+
}
146+
147+
/* Now we're ready to do the real work. */
148+
if (ptype==PREWARM_PREFETCH)
149+
{
150+
#ifdefUSE_PREFETCH
151+
152+
/*
153+
* In prefetch mode, we just hint the OS to read the blocks, but we
154+
* don't know whether it really does it, and we don't wait for it to
155+
* finish.
156+
*
157+
* It would probably be better to pass our prefetch requests in chunks
158+
* of a megabyte or maybe even a whole segment at a time, but there's
159+
* no practical way to do that at present without a gross modularity
160+
* violation, so we just do this.
161+
*/
162+
for (block=first_block;block <=last_block;++block)
163+
{
164+
PrefetchBuffer(rel,forkNumber,block);
165+
++blocks_done;
166+
}
167+
#else
168+
ereport(ERROR,
169+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
170+
errmsg("prefetch is not supported by this build")));
171+
#endif
172+
}
173+
elseif (ptype==PREWARM_READ)
174+
{
175+
/*
176+
* In read mode, we actually read the blocks, but not into shared
177+
* buffers. This is more portable than prefetch mode (it works
178+
* everywhere) and is synchronous.
179+
*/
180+
for (block=first_block;block <=last_block;++block)
181+
{
182+
smgrread(rel->rd_smgr,forkNumber,block,blockbuffer);
183+
++blocks_done;
184+
}
185+
}
186+
elseif (ptype==PREWARM_BUFFER)
187+
{
188+
/*
189+
* In buffer mode, we actually pull the data into shared_buffers.
190+
*/
191+
for (block=first_block;block <=last_block;++block)
192+
{
193+
Bufferbuf;
194+
195+
buf=ReadBufferExtended(rel,forkNumber,block,RBM_NORMAL,NULL);
196+
ReleaseBuffer(buf);
197+
++blocks_done;
198+
}
199+
}
200+
201+
/* Close relation, release lock. */
202+
relation_close(rel,AccessShareLock);
203+
204+
PG_RETURN_INT64(blocks_done);
205+
}

‎contrib/pg_prewarm/pg_prewarm.control

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# pg_prewarm extension
2+
comment = 'prewarm relation data'
3+
default_version = '1.0'
4+
module_pathname = '$libdir/pg_prewarm'
5+
relocatable = true

‎doc/src/sgml/contrib.sgml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ CREATE EXTENSION <replaceable>module_name</> FROM unpackaged;
128128
&pgbuffercache;
129129
&pgcrypto;
130130
&pgfreespacemap;
131+
&pgprewarm;
131132
&pgrowlocks;
132133
&pgstatstatements;
133134
&pgstattuple;

‎doc/src/sgml/filelist.sgml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@
126126
<!ENTITY pgbuffercache SYSTEM "pgbuffercache.sgml">
127127
<!ENTITY pgcrypto SYSTEM "pgcrypto.sgml">
128128
<!ENTITY pgfreespacemap SYSTEM "pgfreespacemap.sgml">
129+
<!ENTITY pgprewarm SYSTEM "pgprewarm.sgml">
129130
<!ENTITY pgrowlocks SYSTEM "pgrowlocks.sgml">
130131
<!ENTITY pgstandby SYSTEM "pgstandby.sgml">
131132
<!ENTITY pgstatstatements SYSTEM "pgstatstatements.sgml">

‎doc/src/sgml/pgprewarm.sgml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<!-- doc/src/sgml/pgprewarm.sgml -->
2+
3+
<sect1 id="pgprewarm" xreflabel="pg_prewarm">
4+
<title>pg_prewarm</title>
5+
6+
<indexterm zone="pgprewarm">
7+
<primary>pg_prewarm</primary>
8+
</indexterm>
9+
10+
<para>
11+
The <filename>pg_prewarm</filename> module provides a convenient way
12+
to load relation data into either the operating system buffer cache
13+
or the <productname>PostgreSQL</productname> buffer cache.
14+
</para>
15+
16+
<sect2>
17+
<title>Functions</title>
18+
19+
<synopsis>
20+
pg_prewarm(regclass, mode text default 'buffer', fork text default 'main',
21+
first_block int8 default null,
22+
last_block int8 default null) RETURNS int8
23+
</synopsis>
24+
25+
<para>
26+
The first argument is the relation to be prewarmed. The second argument
27+
is the prewarming method to be used, as further discussed below; the third
28+
is the relation fork to be prewarmed, usually <literal>main</literal>.
29+
The fourth argument is the first block number to prewarm
30+
(<literal>NULL</literal> is accepted as a synonym for zero). The fifth
31+
argument is the last block number to prewarm (<literal>NULL</literal>
32+
means prewarm through the last block in the relation). The return value
33+
is the number of blocks prewarmed.
34+
</para>
35+
36+
<para>
37+
There are three available prewarming methods. <literal>prefetch</literal>
38+
issues asynchronous prefetch requests to the operating system, if this is
39+
supported, or throws an error otherwise. <literal>read</literal> reads
40+
the requested range of blocks; unlike <literal>prefetch</literal>, this is
41+
synchronous and supported on all platforms and builds, but may be slower.
42+
<literal>buffer</literal> reads the requested range of blocks into the
43+
database buffer cache.
44+
</para>
45+
46+
<para>
47+
Note that with any of these methods, attempting to prewarm more blocks than
48+
can be cached &mdash; by the OS when using <literal>prefetch</literal> or
49+
<literal>read</literal>, or by <productname>PostgreSQL</productname> when
50+
using <literal>buffer</literal> &mdash; will likely result in lower-numbered
51+
blocks being evicted as higher numbered blocks are read in. Prewarmed data
52+
also enjoys no special protection from cache evictions, so it is possible
53+
for other system activity may evict the newly prewarmed blocks shortly after
54+
they are read; conversely, prewarming may also evict other data from cache.
55+
For these reasons, prewarming is typically most useful at startup, when
56+
caches are largely empty.
57+
</para>
58+
</sect2>
59+
60+
<sect2>
61+
<title>Author</title>
62+
63+
<para>
64+
Robert Haas <email>rhaas@postgresql.org</email>
65+
</para>
66+
</sect2>
67+
68+
</sect1>

‎src/tools/pgindent/typedefs.list

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,6 +1334,7 @@ PostParseColumnRefHook
13341334
PostgresPollingStatusType
13351335
PostingItem
13361336
PreParseColumnRefHook
1337+
PrewarmType
13371338
PredClass
13381339
PredIterInfo
13391340
PredIterInfoData

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp