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

Commitca65f21

Browse files
Files for pg_archivecleanup
1 parent25fee5c commitca65f21

File tree

2 files changed

+336
-0
lines changed

2 files changed

+336
-0
lines changed

‎contrib/pg_archivecleanup/Makefile

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# $PostgreSQL: pgsql/contrib/pg_archivecleanup/Makefile,v 1.1 2010/06/14 16:19:24 sriggs Exp $
2+
3+
PGFILEDESC = "pg_archivecleanup - cleans archive when used with streaming replication"
4+
PGAPPICON=win32
5+
6+
PROGRAM = pg_archivecleanup
7+
OBJS= pg_archivecleanup.o
8+
9+
ifdefUSE_PGXS
10+
PG_CONFIG = pg_config
11+
PGXS :=$(shell$(PG_CONFIG) --pgxs)
12+
include$(PGXS)
13+
else
14+
subdir = contrib/pg_archivecleanup
15+
top_builddir = ../..
16+
include$(top_builddir)/src/Makefile.global
17+
include$(top_srcdir)/contrib/contrib-global.mk
18+
endif
Lines changed: 318 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
1+
/*
2+
* $PostgreSQL: pgsql/contrib/pg_archivecleanup/pg_archivecleanup.c,v 1.1 2010/06/14 16:19:24 sriggs Exp $
3+
*
4+
* pg_archivecleanup.c
5+
*
6+
* Production-ready example of an archive_cleanup_command
7+
* used to clean an archive when using standby_mode = on in 9.0
8+
* or for standalone use for any version of PostgreSQL 8.0+.
9+
*
10+
* Original author:Simon Riggs simon@2ndquadrant.com
11+
* Current maintainer:Simon Riggs
12+
*/
13+
#include"postgres_fe.h"
14+
15+
#include<ctype.h>
16+
#include<dirent.h>
17+
#include<sys/stat.h>
18+
#include<fcntl.h>
19+
#include<signal.h>
20+
21+
#ifdefWIN32
22+
intgetopt(intargc,char*constargv[],constchar*optstring);
23+
#else
24+
#include<sys/time.h>
25+
#include<unistd.h>
26+
27+
#ifdefHAVE_GETOPT_H
28+
#include<getopt.h>
29+
#endif
30+
#endif/* ! WIN32 */
31+
32+
externchar*optarg;
33+
externintoptind;
34+
35+
constchar*progname;
36+
37+
/* Options and defaults */
38+
booldebug= false;/* are we debugging? */
39+
40+
char*archiveLocation;/* where to find the archive? */
41+
char*restartWALFileName;/* the file from which we can restart restore */
42+
charWALFilePath[MAXPGPATH];/* the file path including archive */
43+
charexclusiveCleanupFileName[MAXPGPATH];/* the oldest file we want to
44+
* remain in archive */
45+
46+
structstatstat_buf;
47+
48+
/* =====================================================================
49+
*
50+
* Customizable section
51+
*
52+
* =====================================================================
53+
*
54+
*Currently, this section assumes that the Archive is a locally
55+
*accessible directory. If you want to make other assumptions,
56+
*such as using a vendor-specific archive and access API, these
57+
*routines are the ones you'll need to change. You're
58+
*enouraged to submit any changes to pgsql-hackers@postgresql.org
59+
*or personally to the current maintainer. Those changes may be
60+
*folded in to later versions of this program.
61+
*/
62+
63+
#defineXLOG_DATA_FNAME_LEN24
64+
/* Reworked from access/xlog_internal.h */
65+
#defineXLogFileName(fname,tli,log,seg)\
66+
snprintf(fname, XLOG_DATA_FNAME_LEN + 1, "%08X%08X%08X", tli, log, seg)
67+
#defineXLOG_BACKUP_FNAME_LEN40
68+
69+
/*
70+
*Initialize allows customized commands into the archive cleanup program.
71+
*
72+
* You may wish to add code to check for tape libraries, etc..
73+
*/
74+
staticvoid
75+
Initialize(void)
76+
{
77+
/*
78+
* This code assumes that archiveLocation is a directory, so we use
79+
* stat to test if it's accessible.
80+
*/
81+
if (stat(archiveLocation,&stat_buf)!=0)
82+
{
83+
fprintf(stderr,"%s: archiveLocation \"%s\" does not exist\n",progname,archiveLocation);
84+
fflush(stderr);
85+
exit(2);
86+
}
87+
}
88+
89+
staticvoid
90+
CleanupPriorWALFiles(void)
91+
{
92+
intrc;
93+
DIR*xldir;
94+
structdirent*xlde;
95+
96+
if ((xldir=opendir(archiveLocation))!=NULL)
97+
{
98+
while ((xlde=readdir(xldir))!=NULL)
99+
{
100+
/*
101+
* We ignore the timeline part of the XLOG segment identifiers
102+
* in deciding whether a segment is still needed. This
103+
* ensures that we won't prematurely remove a segment from a
104+
* parent timeline. We could probably be a little more
105+
* proactive about removing segments of non-parent timelines,
106+
* but that would be a whole lot more complicated.
107+
*
108+
* We use the alphanumeric sorting property of the filenames
109+
* to decide which ones are earlier than the
110+
* exclusiveCleanupFileName file. Note that this means files
111+
* are not removed in the order they were originally written,
112+
* in case this worries you.
113+
*/
114+
if (strlen(xlde->d_name)==XLOG_DATA_FNAME_LEN&&
115+
strspn(xlde->d_name,"0123456789ABCDEF")==XLOG_DATA_FNAME_LEN&&
116+
strcmp(xlde->d_name+8,exclusiveCleanupFileName+8)<0)
117+
{
118+
#ifdefWIN32
119+
snprintf(WALFilePath,MAXPGPATH,"%s\\%s",archiveLocation,xlde->d_name);
120+
#else
121+
snprintf(WALFilePath,MAXPGPATH,"%s/%s",archiveLocation,xlde->d_name);
122+
#endif
123+
124+
if (debug)
125+
fprintf(stderr,"\n%s: removing \"%s\"",progname,WALFilePath);
126+
127+
rc=unlink(WALFilePath);
128+
if (rc!=0)
129+
{
130+
fprintf(stderr,"\n%s: ERROR failed to remove \"%s\": %s",
131+
progname,WALFilePath,strerror(errno));
132+
break;
133+
}
134+
}
135+
}
136+
if (debug)
137+
fprintf(stderr,"\n");
138+
}
139+
else
140+
fprintf(stderr,"%s: archiveLocation \"%s\" open error\n",progname,archiveLocation);
141+
142+
closedir(xldir);
143+
fflush(stderr);
144+
}
145+
146+
/*
147+
* SetWALFileNameForCleanup()
148+
*
149+
* Set the earliest WAL filename that we want to keep on the archive
150+
* and decide whether we need_cleanup
151+
*/
152+
staticvoid
153+
SetWALFileNameForCleanup(void)
154+
{
155+
boolfnameOK= false;
156+
157+
/*
158+
* If restartWALFileName is a WAL file name then just use it directly.
159+
* If restartWALFileName is a .backup filename, make sure we use
160+
* the prefix of the filename, otherwise we will remove wrong files
161+
* since 000000010000000000000010.00000020.backup is after
162+
* 000000010000000000000010.
163+
*/
164+
if (strlen(restartWALFileName)==XLOG_DATA_FNAME_LEN&&
165+
strspn(restartWALFileName,"0123456789ABCDEF")==XLOG_DATA_FNAME_LEN)
166+
{
167+
strcpy(exclusiveCleanupFileName,restartWALFileName);
168+
fnameOK= true;
169+
}
170+
elseif (strlen(restartWALFileName)==XLOG_BACKUP_FNAME_LEN)
171+
{
172+
intargs;
173+
uint32tli=1,
174+
log=0,
175+
seg=0,
176+
offset=0;
177+
args=sscanf(restartWALFileName,"%08X%08X%08X.%08X.backup",&tli,&log,&seg,&offset);
178+
if (args==4)
179+
{
180+
fnameOK= true;
181+
/*
182+
* Use just the prefix of the filename, ignore everything after first period
183+
*/
184+
XLogFileName(exclusiveCleanupFileName,tli,log,seg);
185+
}
186+
}
187+
188+
if (!fnameOK)
189+
{
190+
fprintf(stderr,"%s: invalid filename input\n",progname);
191+
fprintf(stderr,"Try \"%s --help\" for more information.\n",progname);
192+
exit(2);
193+
}
194+
}
195+
196+
/* =====================================================================
197+
* End of Customizable section
198+
* =====================================================================
199+
*/
200+
201+
staticvoid
202+
usage(void)
203+
{
204+
printf("%s removes older WAL files from PostgreSQL archives.\n\n",progname);
205+
printf("Usage:\n");
206+
printf(" %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n",progname);
207+
printf("\n"
208+
"for use as an archive_cleanup_command in the recovery.conf when standby_mode = on:\n"
209+
" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n"
210+
"e.g.\n"
211+
" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n");
212+
printf("\n"
213+
"or for use as a standalone archive cleaner:\n"
214+
"e.g.\n"
215+
" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n");
216+
printf("\nOptions:\n");
217+
printf(" -d generates debug output (verbose mode)\n");
218+
printf(" --help show this help, then exit\n");
219+
printf(" --version output version information, then exit\n");
220+
printf("\nReport bugs to <pgsql-bugs@postgresql.org>.\n");
221+
}
222+
223+
/*------------ MAIN ----------------------------------------*/
224+
int
225+
main(intargc,char**argv)
226+
{
227+
intc;
228+
229+
progname=get_progname(argv[0]);
230+
231+
if (argc>1)
232+
{
233+
if (strcmp(argv[1],"--help")==0||strcmp(argv[1],"-?")==0)
234+
{
235+
usage();
236+
exit(0);
237+
}
238+
if (strcmp(argv[1],"--version")==0||strcmp(argv[1],"-V")==0)
239+
{
240+
puts("pg_archivecleanup (PostgreSQL) "PG_VERSION);
241+
exit(0);
242+
}
243+
}
244+
245+
while ((c=getopt(argc,argv,"d"))!=-1)
246+
{
247+
switch (c)
248+
{
249+
case'd':/* Debug mode */
250+
debug= true;
251+
break;
252+
default:
253+
fprintf(stderr,"Try \"%s --help\" for more information.\n",progname);
254+
exit(2);
255+
break;
256+
}
257+
}
258+
259+
/*
260+
* We will go to the archiveLocation to check restartWALFileName.
261+
* restartWALFileName may not exist anymore, which would not be an error, so
262+
* we separate the archiveLocation and restartWALFileName so we can check
263+
* separately whether archiveLocation exists, if not that is an error
264+
*/
265+
if (optind<argc)
266+
{
267+
archiveLocation=argv[optind];
268+
optind++;
269+
}
270+
else
271+
{
272+
fprintf(stderr,"%s: must specify archive location\n",progname);
273+
fprintf(stderr,"Try \"%s --help\" for more information.\n",progname);
274+
exit(2);
275+
}
276+
277+
if (optind<argc)
278+
{
279+
restartWALFileName=argv[optind];
280+
optind++;
281+
}
282+
else
283+
{
284+
fprintf(stderr,"%s: must specify restartfilename\n",progname);
285+
fprintf(stderr,"Try \"%s --help\" for more information.\n",progname);
286+
exit(2);
287+
}
288+
289+
if (optind<argc)
290+
{
291+
fprintf(stderr,"%s: too many parameters\n",progname);
292+
fprintf(stderr,"Try \"%s --help\" for more information.\n",progname);
293+
exit(2);
294+
}
295+
296+
/*
297+
* Check archive exists and other initialization if required.
298+
*/
299+
Initialize();
300+
301+
/*
302+
* Check filename is a valid name, then process to find cut-off
303+
*/
304+
SetWALFileNameForCleanup();
305+
306+
if (debug)
307+
{
308+
fprintf(stderr,"%s: keep WAL file %s and later",progname,exclusiveCleanupFileName);
309+
fflush(stderr);
310+
}
311+
312+
/*
313+
* Remove WAL files older than cut-off
314+
*/
315+
CleanupPriorWALFiles();
316+
317+
exit(0);
318+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp