]> granicus.if.org Git - postgresql/blob - src/backend/postmaster/pgarch.c
Add functions pg_start_backup, pg_stop_backup to create backup label
[postgresql] / src / backend / postmaster / pgarch.c
1 /*-------------------------------------------------------------------------
2  *
3  * pgarch.c
4  *
5  *      PostgreSQL WAL archiver
6  *
7  *  All functions relating to archiver are included here
8  *
9  *  - All functions executed by archiver process
10  *
11  *  - archiver is forked from postmaster, and the two
12  *  processes then communicate using signals. All functions
13  *  executed by postmaster are included in this file.
14  *
15  *  Initial author: Simon Riggs     simon@2ndquadrant.com
16  *
17  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
18  * Portions Copyright (c) 1994, Regents of the University of California
19  *
20  *
21  * IDENTIFICATION
22  *        $PostgreSQL: pgsql/src/backend/postmaster/pgarch.c,v 1.4 2004/08/03 20:32:33 tgl Exp $
23  *
24  *-------------------------------------------------------------------------
25  */
26 #include "postgres.h"
27
28 #include <fcntl.h>
29 #include <signal.h>
30 #include <time.h>
31 #include <sys/time.h>
32 #include <unistd.h>
33
34 #include "access/xlog_internal.h"
35 #include "libpq/pqsignal.h"
36 #include "miscadmin.h"
37 #include "postmaster/pgarch.h"
38 #include "postmaster/postmaster.h"
39 #include "storage/fd.h"
40 #include "storage/ipc.h"
41 #include "storage/pg_shmem.h"
42 #include "storage/pmsignal.h"
43 #include "utils/guc.h"
44 #include "utils/ps_status.h"
45
46
47 /* ----------
48  * Timer definitions.
49  * ----------
50  */
51 #define PGARCH_AUTOWAKE_INTERVAL 60             /* How often to force a poll of
52                                                                                  * the archive status directory;
53                                                                                  * in seconds. */
54 #define PGARCH_RESTART_INTERVAL 60              /* How often to attempt to restart
55                                                                                  * a failed archiver; in seconds. */
56
57 /* ----------
58  * Archiver control info.
59  *
60  * We expect that archivable files within pg_xlog will have names between
61  * MIN_XFN_CHARS and MAX_XFN_CHARS in length, consisting only of characters
62  * appearing in VALID_XFN_CHARS.  The status files in archive_status have
63  * corresponding names with ".ready" or ".done" appended.
64  * ----------
65  */
66 #define MIN_XFN_CHARS   16
67 #define MAX_XFN_CHARS   40
68 #define VALID_XFN_CHARS "0123456789ABCDEF.history.backup"
69
70 #define NUM_ARCHIVE_RETRIES 3
71
72
73 /* ----------
74  * Local data
75  * ----------
76  */
77 static time_t last_pgarch_start_time;
78
79 /*
80  * Flags set by interrupt handlers for later service in the main loop.
81  */
82 static volatile sig_atomic_t got_SIGHUP = false;
83 static volatile sig_atomic_t wakened = false;
84
85 /* ----------
86  * Local function forward declarations
87  * ----------
88  */
89 #ifdef EXEC_BACKEND
90 static pid_t pgarch_forkexec(void);
91 #endif
92
93 NON_EXEC_STATIC void PgArchiverMain(int argc, char *argv[]);
94 static void pgarch_exit(SIGNAL_ARGS);
95 static void ArchSigHupHandler(SIGNAL_ARGS);
96 static void pgarch_waken(SIGNAL_ARGS);
97 static void pgarch_MainLoop(void);
98 static void pgarch_ArchiverCopyLoop(void);
99 static bool pgarch_archiveXlog(char *xlog);
100 static bool pgarch_readyXlog(char *xlog);
101 static void pgarch_archiveDone(char *xlog);
102
103
104 /* ------------------------------------------------------------
105  * Public functions called from postmaster follow
106  * ------------------------------------------------------------
107  */
108
109 /*
110  * pgarch_start
111  *
112  *      Called from postmaster at startup or after an existing archiver
113  *      died.  Attempt to fire up a fresh archiver process.
114  *
115  *      Returns PID of child process, or 0 if fail.
116  *
117  *      Note: if fail, we will be called again from the postmaster main loop.
118  */
119 int
120 pgarch_start(void)
121 {
122         time_t          curtime;
123         pid_t           pgArchPid;
124
125         /*
126          * Do nothing if no archiver needed
127          */
128         if (!XLogArchivingActive())
129                 return 0;
130
131         /*
132          * Do nothing if too soon since last archiver start.  This is a
133          * safety valve to protect against continuous respawn attempts if the
134          * archiver is dying immediately at launch. Note that since we will
135          * be re-called from the postmaster main loop, we will get another
136          * chance later.
137          */
138         curtime = time(NULL);
139         if ((unsigned int) (curtime - last_pgarch_start_time) <
140                 (unsigned int) PGARCH_RESTART_INTERVAL)
141                 return 0;
142         last_pgarch_start_time = curtime;
143
144         fflush(stdout);
145         fflush(stderr);
146
147 #ifdef __BEOS__
148         /* Specific beos actions before backend startup */
149         beos_before_backend_startup();
150 #endif
151
152 #ifdef EXEC_BACKEND
153         switch ((pgArchPid = pgarch_forkexec()))
154 #else
155         switch ((pgArchPid = fork()))
156 #endif
157         {
158                 case -1:
159 #ifdef __BEOS__
160                         /* Specific beos actions */
161                         beos_backend_startup_failed();
162 #endif
163                         ereport(LOG,
164                                         (errmsg("could not fork archiver: %m")));
165                         return 0;
166
167 #ifndef EXEC_BACKEND
168                 case 0:
169                         /* in postmaster child ... */
170 #ifdef __BEOS__
171                         /* Specific beos actions after backend startup */
172                         beos_backend_startup();
173 #endif
174                         /* Close the postmaster's sockets */
175                         ClosePostmasterPorts();
176
177                         /* Drop our connection to postmaster's shared memory, as well */
178                         PGSharedMemoryDetach();
179
180                         PgArchiverMain(0, NULL);
181                         break;
182 #endif
183
184                 default:
185                         return (int) pgArchPid;
186         }
187
188         /* shouldn't get here */
189         return 0;
190 }
191
192 /* ------------------------------------------------------------
193  * Local functions called by archiver follow
194  * ------------------------------------------------------------
195  */
196
197
198 #ifdef EXEC_BACKEND
199
200 /*
201  * pgarch_forkexec() -
202  *
203  * Format up the arglist for, then fork and exec, archive process
204  */
205 static pid_t
206 pgarch_forkexec(void)
207 {
208         char *av[10];
209         int ac = 0;
210
211         av[ac++] = "postgres";
212
213         av[ac++] = "-forkarch";
214
215         av[ac++] = NULL;                        /* filled in by postmaster_forkexec */
216
217         av[ac] = NULL;
218         Assert(ac < lengthof(av));
219
220         return postmaster_forkexec(ac, av);
221 }
222
223 #endif /* EXEC_BACKEND */
224
225
226 /*
227  * PgArchiverMain
228  *
229  *      The argc/argv parameters are valid only in EXEC_BACKEND case.  However,
230  *      since we don't use 'em, it hardly matters...
231  */
232 NON_EXEC_STATIC void
233 PgArchiverMain(int argc, char *argv[])
234 {
235     IsUnderPostmaster = true;   /* we are a postmaster subprocess now */
236
237     MyProcPid = getpid();               /* reset MyProcPid */
238
239         /* Lose the postmaster's on-exit routines */
240         on_exit_reset();
241
242     /*
243      * Ignore all signals usually bound to some action in the postmaster,
244          * except for SIGHUP, SIGUSR1 and SIGQUIT.
245      */
246     pqsignal(SIGHUP, ArchSigHupHandler);
247     pqsignal(SIGINT, SIG_IGN);
248     pqsignal(SIGTERM, SIG_IGN);
249     pqsignal(SIGQUIT, pgarch_exit);
250     pqsignal(SIGALRM, SIG_IGN);
251     pqsignal(SIGPIPE, SIG_IGN);
252     pqsignal(SIGUSR1, pgarch_waken);
253     pqsignal(SIGUSR2, SIG_IGN);
254     pqsignal(SIGCHLD, SIG_DFL);
255     pqsignal(SIGTTIN, SIG_DFL);
256     pqsignal(SIGTTOU, SIG_DFL);
257     pqsignal(SIGCONT, SIG_DFL);
258     pqsignal(SIGWINCH, SIG_DFL);
259     PG_SETMASK(&UnBlockSig);
260
261     /*
262      * Identify myself via ps
263      */
264     init_ps_display("archiver process", "", "");
265     set_ps_display("");
266
267     /* Init XLOG file paths --- needed in EXEC_BACKEND case */
268         XLOGPathInit();
269
270     pgarch_MainLoop();
271
272         exit(0);
273 }
274
275 /* SIGQUIT signal handler for archiver process */
276 static void
277 pgarch_exit(SIGNAL_ARGS)
278 {
279         /*
280          * For now, we just nail the doors shut and get out of town.  It might
281          * seem cleaner to finish up any pending archive copies, but there's
282          * a nontrivial risk that init will kill us partway through.
283          */
284     exit(0);
285 }
286
287 /* SIGHUP: set flag to re-read config file at next convenient time */
288 static void
289 ArchSigHupHandler(SIGNAL_ARGS)
290 {
291         got_SIGHUP = true;
292 }
293
294 /* SIGUSR1 signal handler for archiver process */
295 static void
296 pgarch_waken(SIGNAL_ARGS)
297 {
298         wakened = true;
299 }
300
301 /*
302  * pgarch_MainLoop
303  *
304  * Main loop for archiver
305  */
306 static void
307 pgarch_MainLoop(void)
308 {
309         time_t last_copy_time = 0;
310         time_t curtime;
311
312         /*
313          * We run the copy loop immediately upon entry, in case there are
314          * unarchived files left over from a previous database run (or maybe
315          * the archiver died unexpectedly).  After that we wait for a signal
316          * or timeout before doing more.
317          */
318         wakened = true;
319
320         do {
321
322                 /* Check for config update */
323                 if (got_SIGHUP)
324                 {
325                         got_SIGHUP = false;
326                         ProcessConfigFile(PGC_SIGHUP);
327                         if (!XLogArchivingActive())
328                                 break;                  /* user wants us to shut down */
329                 }
330
331                 /* Do what we're here for */
332                 if (wakened)
333                 {
334                         wakened = false;
335                         pgarch_ArchiverCopyLoop();
336                         last_copy_time = time(NULL);
337                 }
338
339                 /*
340                  * There shouldn't be anything for the archiver to do except
341                  * to wait for a signal, so we could use pause(3) here...
342                  * ...however, the archiver exists to protect our data, so
343                  * she wakes up occasionally to allow herself to be proactive.
344                  * In particular this avoids getting stuck if a signal arrives
345                  * just before we enter sleep().
346                  */
347                 if (!wakened)
348                 {
349                         sleep(PGARCH_AUTOWAKE_INTERVAL);
350
351                         curtime = time(NULL);
352                         if ((unsigned int) (curtime - last_copy_time) >=
353                                 (unsigned int) PGARCH_AUTOWAKE_INTERVAL)
354                                 wakened = true;
355                 }
356         } while (PostmasterIsAlive(true));
357 }
358
359 /*
360  * pgarch_ArchiverCopyLoop
361  *
362  * Archives all outstanding xlogs then returns
363  */
364 static void
365 pgarch_ArchiverCopyLoop(void)
366 {
367         char    xlog[MAX_XFN_CHARS + 1];
368
369     /*
370      * loop through all xlogs with archive_status of .ready
371      * and archive them...mostly we expect this to be a single
372      * file, though it is possible some backend will add
373      * files onto the list of those that need archiving while we
374      * are still copying earlier archives
375      */
376         while (pgarch_readyXlog(xlog))
377         {
378                 int     failures = 0;
379
380                 for (;;)
381                 {
382                         if (pgarch_archiveXlog(xlog))
383                         {
384                                 /* successful */
385                                 pgarch_archiveDone(xlog);
386                                 break;                  /* out of inner retry loop */
387                         }
388                         else
389                         {
390                                 if (++failures >= NUM_ARCHIVE_RETRIES)
391                                 {
392                                         ereport(WARNING,
393                                                         (errmsg("transaction log file \"%s\" could not be archived",
394                                                                         xlog)));
395                                         return;         /* give up archiving for now */
396                                 }
397                                 sleep(1);               /* wait a bit before retrying */
398                         }
399                 }
400         }
401 }
402
403 /*
404  * pgarch_archiveXlog
405  *
406  * Invokes system(3) to copy one archive file to wherever it should go
407  *
408  * Returns true if successful
409  */
410 static bool
411 pgarch_archiveXlog(char *xlog)
412 {
413     char xlogarchcmd[MAXPGPATH];
414     char pathname[MAXPGPATH];
415         char *dp;
416         char *endp;
417         const char *sp;
418     int rc;
419
420     snprintf(pathname, MAXPGPATH, "%s/%s", XLogDir, xlog);
421
422         /*
423          * construct the command to be executed
424          */
425         dp = xlogarchcmd;
426         endp = xlogarchcmd + MAXPGPATH - 1;
427         *endp = '\0';
428
429         for (sp = XLogArchiveCommand; *sp; sp++)
430         {
431                 if (*sp == '%')
432                 {
433                         switch (sp[1])
434                         {
435                                 case 'p':
436                                         /* %p: full path of source file */
437                                         sp++;
438                                         StrNCpy(dp, pathname, endp-dp);
439                                         dp += strlen(dp);
440                                         break;
441                                 case 'f':
442                                         /* %f: filename of source file */
443                                         sp++;
444                                         StrNCpy(dp, xlog, endp-dp);
445                                         dp += strlen(dp);
446                                         break;
447                                 case '%':
448                                         /* convert %% to a single % */
449                                         sp++;
450                                         if (dp < endp)
451                                                 *dp++ = *sp;
452                                         break;
453                                 default:
454                                         /* otherwise treat the % as not special */
455                                         if (dp < endp)
456                                                 *dp++ = *sp;
457                                         break;
458                         }
459                 }
460                 else
461                 {
462                         if (dp < endp)
463                                 *dp++ = *sp;
464                 }
465         }
466         *dp = '\0';
467
468         ereport(DEBUG3,
469             (errmsg_internal("executing archive command \"%s\"",
470                                                          xlogarchcmd)));
471     rc = system(xlogarchcmd);
472     if (rc != 0) {
473         ereport(LOG,
474                                 (errmsg("archive command \"%s\" failed: return code %d",
475                                                 xlogarchcmd, rc)));
476         return false;
477     }
478         ereport(LOG,
479             (errmsg("archived transaction log file \"%s\"", xlog)));
480
481     return true;
482 }
483
484 /*
485  * pgarch_readyXlog
486  *
487  * Return name of the oldest xlog file that has not yet been archived.
488  * No notification is set that file archiving is now in progress, so
489  * this would need to be extended if multiple concurrent archival
490  * tasks were created. If a failure occurs, we will completely
491  * re-copy the file at the next available opportunity.
492  *
493  * It is important that we return the oldest, so that we archive xlogs
494  * in order that they were written, for two reasons:
495  * 1) to maintain the sequential chain of xlogs required for recovery
496  * 2) because the oldest ones will sooner become candidates for
497  * recycling at time of checkpoint
498  *
499  * NOTE: the "oldest" comparison will presently consider all segments of
500  * a timeline with a smaller ID to be older than all segments of a timeline
501  * with a larger ID; the net result being that past timelines are given
502  * higher priority for archiving.  This seems okay, or at least not
503  * obviously worth changing.
504  */
505 static bool
506 pgarch_readyXlog(char *xlog)
507 {
508         /*
509          * open xlog status directory and read through list of
510          * xlogs that have the .ready suffix, looking for earliest file.
511          * It is possible to optimise this code, though only a single
512          * file is expected on the vast majority of calls, so....
513          */
514         char            XLogArchiveStatusDir[MAXPGPATH];
515         char            newxlog[MAX_XFN_CHARS + 6 + 1];
516         DIR                 *rldir;
517         struct dirent   *rlde;
518         bool            found = false;
519
520     snprintf(XLogArchiveStatusDir, MAXPGPATH, "%s/archive_status", XLogDir);
521         rldir = AllocateDir(XLogArchiveStatusDir);
522         if (rldir == NULL)
523                 ereport(ERROR,
524                         (errcode_for_file_access(),
525                          errmsg("could not open archive status directory \"%s\": %m",
526                                         XLogArchiveStatusDir)));
527
528         errno = 0;
529         while ((rlde = readdir(rldir)) != NULL)
530         {
531                 int             basenamelen = (int) strlen(rlde->d_name) - 6;
532
533                 if (basenamelen >= MIN_XFN_CHARS &&
534                         basenamelen <= MAX_XFN_CHARS &&
535                         strspn(rlde->d_name, VALID_XFN_CHARS) >= basenamelen &&
536                         strcmp(rlde->d_name + basenamelen, ".ready") == 0)
537                 {
538                     if (!found) {
539                                 strcpy(newxlog, rlde->d_name);
540                                 found = true;
541                     } else {
542                         if (strcmp(rlde->d_name, newxlog) < 0)
543                                         strcpy(newxlog, rlde->d_name);
544                     }
545                 }
546
547                 errno = 0;
548         }
549 #ifdef WIN32
550         /* This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but
551            not in released version */
552         if (GetLastError() == ERROR_NO_MORE_FILES)
553                 errno = 0;
554 #endif
555         if (errno)
556                 ereport(ERROR,
557                                 (errcode_for_file_access(),
558                                  errmsg("could not read archive status directory \"%s\": %m",
559                                                 XLogArchiveStatusDir)));
560         FreeDir(rldir);
561
562         if (found)
563         {
564                 /* truncate off the .ready */
565                 newxlog[strlen(newxlog) - 6] = '\0';
566                 strcpy(xlog, newxlog);
567         }
568         return found;
569 }
570
571 /*
572  * pgarch_archiveDone
573  *
574  * Emit notification that an xlog file has been successfully archived.
575  * We do this by renaming the status file from NNN.ready to NNN.done.
576  * Eventually, a checkpoint process will notice this and delete both the
577  * NNN.done file and the xlog file itself.
578  */
579 static void
580 pgarch_archiveDone(char *xlog)
581 {
582     char                rlogready[MAXPGPATH];
583     char                rlogdone[MAXPGPATH];
584
585         StatusFilePath(rlogready, xlog, ".ready");
586         StatusFilePath(rlogdone, xlog, ".done");
587         if (rename(rlogready, rlogdone) < 0)
588                 ereport(WARNING,
589                                 (errcode_for_file_access(),
590                                  errmsg("could not rename file \"%s\" to \"%s\": %m",
591                                                 rlogready, rlogdone)));
592 }