* completes, the file names are stored in ascending order of priority in
* arch_files. pgarch_readyXlog() returns files from arch_files until it
* is empty, at which point another directory scan must be performed.
+ *
+ * We only need this data in the archiver process, so make it a palloc'd
+ * struct rather than a bunch of static arrays.
*/
-static binaryheap *arch_heap = NULL;
-static char arch_filenames[NUM_FILES_PER_DIRECTORY_SCAN][MAX_XFN_CHARS];
-static char *arch_files[NUM_FILES_PER_DIRECTORY_SCAN];
-static int arch_files_size = 0;
+struct arch_files_state
+{
+ binaryheap *arch_heap;
+ int arch_files_size; /* number of live entries in arch_files[] */
+ char *arch_files[NUM_FILES_PER_DIRECTORY_SCAN];
+ /* buffers underlying heap, and later arch_files[], entries: */
+ char arch_filenames[NUM_FILES_PER_DIRECTORY_SCAN][MAX_XFN_CHARS + 1];
+};
+
+static struct arch_files_state *arch_files = NULL;
/*
* Flags set by interrupt handlers for later service in the main loop.
*/
PgArch->pgprocno = MyProc->pgprocno;
+ /* Create workspace for pgarch_readyXlog() */
+ arch_files = palloc(sizeof(struct arch_files_state));
+ arch_files->arch_files_size = 0;
+
/* Initialize our max-heap for prioritizing files to archive. */
- arch_heap = binaryheap_allocate(NUM_FILES_PER_DIRECTORY_SCAN,
- ready_file_comparator, NULL);
+ arch_files->arch_heap = binaryheap_allocate(NUM_FILES_PER_DIRECTORY_SCAN,
+ ready_file_comparator, NULL);
pgarch_MainLoop();
char xlog[MAX_XFN_CHARS + 1];
/* force directory scan in the first call to pgarch_readyXlog() */
- arch_files_size = 0;
+ arch_files->arch_files_size = 0;
/*
* loop through all xlogs with archive_status of .ready and archive
SpinLockRelease(&PgArch->arch_lck);
if (force_dir_scan)
- arch_files_size = 0;
+ arch_files->arch_files_size = 0;
/*
* If we still have stored file names from the previous directory scan,
* is still present, as the archive_command for a previous file may
* have already marked it done.
*/
- while (arch_files_size > 0)
+ while (arch_files->arch_files_size > 0)
{
struct stat st;
char status_file[MAXPGPATH];
char *arch_file;
- arch_files_size--;
- arch_file = arch_files[arch_files_size];
+ arch_files->arch_files_size--;
+ arch_file = arch_files->arch_files[arch_files->arch_files_size];
StatusFilePath(status_file, arch_file, ".ready");
if (stat(status_file, &st) == 0)
errmsg("could not stat file \"%s\": %m", status_file)));
}
+ /* arch_heap is probably empty, but let's make sure */
+ binaryheap_reset(arch_files->arch_heap);
+
/*
* Open the archive status directory and read through the list of files
* with the .ready suffix, looking for the earliest files.
/*
* Store the file in our max-heap if it has a high enough priority.
*/
- if (arch_heap->bh_size < NUM_FILES_PER_DIRECTORY_SCAN)
+ if (arch_files->arch_heap->bh_size < NUM_FILES_PER_DIRECTORY_SCAN)
{
/* If the heap isn't full yet, quickly add it. */
- arch_file = arch_filenames[arch_heap->bh_size];
+ arch_file = arch_files->arch_filenames[arch_files->arch_heap->bh_size];
strcpy(arch_file, basename);
- binaryheap_add_unordered(arch_heap, CStringGetDatum(arch_file));
+ binaryheap_add_unordered(arch_files->arch_heap, CStringGetDatum(arch_file));
/* If we just filled the heap, make it a valid one. */
- if (arch_heap->bh_size == NUM_FILES_PER_DIRECTORY_SCAN)
- binaryheap_build(arch_heap);
+ if (arch_files->arch_heap->bh_size == NUM_FILES_PER_DIRECTORY_SCAN)
+ binaryheap_build(arch_files->arch_heap);
}
- else if (ready_file_comparator(binaryheap_first(arch_heap),
+ else if (ready_file_comparator(binaryheap_first(arch_files->arch_heap),
CStringGetDatum(basename), NULL) > 0)
{
/*
* Remove the lowest priority file and add the current one to
* the heap.
*/
- arch_file = DatumGetCString(binaryheap_remove_first(arch_heap));
+ arch_file = DatumGetCString(binaryheap_remove_first(arch_files->arch_heap));
strcpy(arch_file, basename);
- binaryheap_add(arch_heap, CStringGetDatum(arch_file));
+ binaryheap_add(arch_files->arch_heap, CStringGetDatum(arch_file));
}
}
FreeDir(rldir);
/* If no files were found, simply return. */
- if (arch_heap->bh_size == 0)
+ if (arch_files->arch_heap->bh_size == 0)
return false;
/*
* If we didn't fill the heap, we didn't make it a valid one. Do that
* now.
*/
- if (arch_heap->bh_size < NUM_FILES_PER_DIRECTORY_SCAN)
- binaryheap_build(arch_heap);
+ if (arch_files->arch_heap->bh_size < NUM_FILES_PER_DIRECTORY_SCAN)
+ binaryheap_build(arch_files->arch_heap);
/*
* Fill arch_files array with the files to archive in ascending order
* of priority.
*/
- arch_files_size = arch_heap->bh_size;
- for (int i = 0; i < arch_files_size; i++)
- arch_files[i] = DatumGetCString(binaryheap_remove_first(arch_heap));
+ arch_files->arch_files_size = arch_files->arch_heap->bh_size;
+ for (int i = 0; i < arch_files->arch_files_size; i++)
+ arch_files->arch_files[i] = DatumGetCString(binaryheap_remove_first(arch_files->arch_heap));
/* Return the highest priority file. */
- arch_files_size--;
- strcpy(xlog, arch_files[arch_files_size]);
+ arch_files->arch_files_size--;
+ strcpy(xlog, arch_files->arch_files[arch_files->arch_files_size]);
return true;
}