On Fri, 2010-02-12 at 12:54 +0000, Simon Riggs wrote: > So I suggest that you have a new action that gets called after every > checkpoint to clear down the archive. It will remove all files from the > archive prior to %r. We can implement that as a sequence of unlink()s > from within the server, or we can just call a script to do it. I prefer > the latter approach. However we do it, we need something initiated by > the server to maintain the archive and stop it from overflowing.
Attached patch implements pg_standby for use as an archive_cleanup_command, reusing existing code with new -a option. e.g. archive_cleanup_command = 'pg_standby -a -d /mnt/server/archiverdir %r' Happy to add the archive_cleanup_command into main server as well, if you like. Won't take long. -- Simon Riggs www.2ndQuadrant.com
Index: contrib/pg_standby/pg_standby.c =================================================================== RCS file: /home/sriggs/pg/REPOSITORY/pgsql/contrib/pg_standby/pg_standby.c,v retrieving revision 1.27 diff -c -r1.27 pg_standby.c *** contrib/pg_standby/pg_standby.c 4 Nov 2009 12:51:30 -0000 1.27 --- contrib/pg_standby/pg_standby.c 12 Feb 2010 14:26:42 -0000 *************** *** 53,58 **** --- 53,59 ---- int keepfiles = 0; /* number of WAL files to keep, 0 keep all */ int maxretries = 3; /* number of retries on restore command */ bool debug = false; /* are we debugging? */ + bool cleanup_only = false; /* -a option new for 9.0 */ bool need_cleanup = false; /* do we need to remove files from * archive? */ *************** *** 243,249 **** /* * Work out name of prior file from current filename */ ! if (nextWALFileType == XLOG_DATA) { int rc; DIR *xldir; --- 244,250 ---- /* * Work out name of prior file from current filename */ ! if (cleanup_only || nextWALFileType == XLOG_DATA) { int rc; DIR *xldir; *************** *** 334,340 **** * these files from archive. This shouldn't happen, but better safe * than sorry. */ ! if (strcmp(restartWALFileName, nextWALFileName) > 0) return false; strcpy(exclusiveCleanupFileName, restartWALFileName); --- 335,341 ---- * these files from archive. This shouldn't happen, but better safe * than sorry. */ ! if (!cleanup_only && strcmp(restartWALFileName, nextWALFileName) > 0) return false; strcpy(exclusiveCleanupFileName, restartWALFileName); *************** *** 512,518 **** static void usage(void) { ! printf("%s allows PostgreSQL warm standby servers to be configured.\n\n", progname); printf("Usage:\n"); printf(" %s [OPTION]... ARCHIVELOCATION NEXTWALFILE XLOGFILEPATH [RESTARTWALFILE]\n", progname); printf("\n" --- 513,519 ---- static void usage(void) { ! printf("%s allows PostgreSQL standby servers to be configured.\n\n", progname); printf("Usage:\n"); printf(" %s [OPTION]... ARCHIVELOCATION NEXTWALFILE XLOGFILEPATH [RESTARTWALFILE]\n", progname); printf("\n" *************** *** 520,526 **** --- 521,534 ---- " restore_command = 'pg_standby [OPTION]... ARCHIVELOCATION %%f %%p %%r'\n" "e.g.\n" " restore_command = 'pg_standby -l /mnt/server/archiverdir %%f %%p %%r'\n"); + printf(" %s -a ARCHIVELOCATION RESTARTWALFILE\n", progname); + printf("\n" + "with main intended use as an archive_cleanup_command in the recovery.conf:\n" + " archive_cleanup_command = 'pg_standby -a ARCHIVELOCATION %%r'\n" + "e.g.\n" + " archive_cleanup_command = 'pg_standby -a -d /mnt/server/archiverdir %%r'\n"); printf("\nOptions:\n"); + printf(" -a cleans archive only\n"); printf(" -c copies file from archive (default)\n"); printf(" -d generate lots of debugging output (testing only)\n"); printf(" -k NUMFILESTOKEEP if RESTARTWALFILE not used, removes files prior to limit\n" *************** *** 595,604 **** (void) signal(SIGQUIT, sigquit_handler); #endif ! while ((c = getopt(argc, argv, "cdk:lr:s:t:w:")) != -1) { switch (c) { case 'c': /* Use copy */ restoreCommandType = RESTORE_COMMAND_COPY; break; --- 603,615 ---- (void) signal(SIGQUIT, sigquit_handler); #endif ! while ((c = getopt(argc, argv, "acdk:lr:s:t:w:")) != -1) { switch (c) { + case 'a': /* Cleanup only */ + cleanup_only = true; + break; case 'c': /* Use copy */ restoreCommandType = RESTORE_COMMAND_COPY; break; *************** *** 684,734 **** exit(2); } ! if (optind < argc) ! { ! nextWALFileName = argv[optind]; ! optind++; ! } ! else { ! fprintf(stderr, "%s: use %%f to specify nextWALFileName\n", progname); ! fprintf(stderr, "Try \"%s --help\" for more information.\n", progname); ! exit(2); } if (optind < argc) { ! xlogFilePath = argv[optind]; optind++; } ! else { ! fprintf(stderr, "%s: use %%p to specify xlogFilePath\n", progname); fprintf(stderr, "Try \"%s --help\" for more information.\n", progname); exit(2); } - if (optind < argc) - { - restartWALFileName = argv[optind]; - optind++; - } - CustomizableInitialize(); need_cleanup = SetWALFileNameForCleanup(); if (debug) { ! fprintf(stderr, "Trigger file : %s\n", triggerPath ? triggerPath : "<not set>"); ! fprintf(stderr, "Waiting for WAL file : %s\n", nextWALFileName); ! fprintf(stderr, "WAL file path : %s\n", WALFilePath); ! fprintf(stderr, "Restoring to : %s\n", xlogFilePath); ! fprintf(stderr, "Sleep interval : %d second%s\n", ! sleeptime, (sleeptime > 1 ? "s" : " ")); ! fprintf(stderr, "Max wait interval : %d %s\n", ! maxwaittime, (maxwaittime > 0 ? "seconds" : "forever")); ! fprintf(stderr, "Command for restore : %s\n", restoreCommand); fprintf(stderr, "Keep archive history : "); if (need_cleanup) fprintf(stderr, "%s and later\n", exclusiveCleanupFileName); --- 695,758 ---- exit(2); } ! if (!cleanup_only) { ! if (optind < argc) ! { ! nextWALFileName = argv[optind]; ! optind++; ! } ! else ! { ! fprintf(stderr, "%s: use %%f to specify nextWALFileName\n", progname); ! fprintf(stderr, "Try \"%s --help\" for more information.\n", progname); ! exit(2); ! } ! ! if (optind < argc) ! { ! xlogFilePath = argv[optind]; ! optind++; ! } ! else ! { ! fprintf(stderr, "%s: use %%p to specify xlogFilePath\n", progname); ! fprintf(stderr, "Try \"%s --help\" for more information.\n", progname); ! exit(2); ! } } if (optind < argc) { ! restartWALFileName = argv[optind]; optind++; } ! ! if (cleanup_only && !restartWALFileName) { ! fprintf(stderr, "%s: must specify restart WAL filename\n", progname); fprintf(stderr, "Try \"%s --help\" for more information.\n", progname); exit(2); } CustomizableInitialize(); need_cleanup = SetWALFileNameForCleanup(); if (debug) { ! if (!cleanup_only) ! { ! fprintf(stderr, "Trigger file : %s\n", triggerPath ? triggerPath : "<not set>"); ! fprintf(stderr, "Waiting for WAL file : %s\n", nextWALFileName); ! fprintf(stderr, "WAL file path : %s\n", WALFilePath); ! fprintf(stderr, "Restoring to : %s\n", xlogFilePath); ! fprintf(stderr, "Sleep interval : %d second%s\n", ! sleeptime, (sleeptime > 1 ? "s" : " ")); ! fprintf(stderr, "Max wait interval : %d %s\n", ! maxwaittime, (maxwaittime > 0 ? "seconds" : "forever")); ! fprintf(stderr, "Command for restore : %s\n", restoreCommand); ! } fprintf(stderr, "Keep archive history : "); if (need_cleanup) fprintf(stderr, "%s and later\n", exclusiveCleanupFileName); *************** *** 738,743 **** --- 762,777 ---- } /* + * Cleanup archive immediately if that's all we need to do. + */ + if (cleanup_only) + { + if (need_cleanup) + CustomizableCleanupPriorWALFiles(); + exit(0); + } + + /* * Check for initial history file: always the first file to be requested * It's OK if the file isn't there - all other files need to wait */
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers