@@ -111,11 +111,20 @@ static PgArchData *PgArch = NULL;
111
111
* completes, the file names are stored in ascending order of priority in
112
112
* arch_files. pgarch_readyXlog() returns files from arch_files until it
113
113
* is empty, at which point another directory scan must be performed.
114
+ *
115
+ * We only need this data in the archiver process, so make it a palloc'd
116
+ * struct rather than a bunch of static arrays.
114
117
*/
115
- static binaryheap * arch_heap = NULL ;
116
- static char arch_filenames [NUM_FILES_PER_DIRECTORY_SCAN ][MAX_XFN_CHARS ];
117
- static char * arch_files [NUM_FILES_PER_DIRECTORY_SCAN ];
118
- static int arch_files_size = 0 ;
118
+ struct arch_files_state
119
+ {
120
+ binaryheap * arch_heap ;
121
+ int arch_files_size ; /* number of live entries in arch_files[] */
122
+ char * arch_files [NUM_FILES_PER_DIRECTORY_SCAN ];
123
+ /* buffers underlying heap, and later arch_files[], entries: */
124
+ char arch_filenames [NUM_FILES_PER_DIRECTORY_SCAN ][MAX_XFN_CHARS + 1 ];
125
+ };
126
+
127
+ static struct arch_files_state * arch_files = NULL ;
119
128
120
129
/*
121
130
* Flags set by interrupt handlers for later service in the main loop.
@@ -231,9 +240,13 @@ PgArchiverMain(void)
231
240
*/
232
241
PgArch -> pgprocno = MyProc -> pgprocno ;
233
242
243
+ /* Create workspace for pgarch_readyXlog() */
244
+ arch_files = palloc (sizeof (struct arch_files_state ));
245
+ arch_files -> arch_files_size = 0 ;
246
+
234
247
/* Initialize our max-heap for prioritizing files to archive. */
235
- arch_heap = binaryheap_allocate (NUM_FILES_PER_DIRECTORY_SCAN ,
236
- ready_file_comparator , NULL );
248
+ arch_files -> arch_heap = binaryheap_allocate (NUM_FILES_PER_DIRECTORY_SCAN ,
249
+ ready_file_comparator , NULL );
237
250
238
251
pgarch_MainLoop ();
239
252
@@ -363,7 +376,7 @@ pgarch_ArchiverCopyLoop(void)
363
376
char xlog [MAX_XFN_CHARS + 1 ];
364
377
365
378
/* force directory scan in the first call to pgarch_readyXlog() */
366
- arch_files_size = 0 ;
379
+ arch_files -> arch_files_size = 0 ;
367
380
368
381
/*
369
382
* loop through all xlogs with archive_status of .ready and archive
@@ -658,22 +671,22 @@ pgarch_readyXlog(char *xlog)
658
671
SpinLockRelease (& PgArch -> arch_lck );
659
672
660
673
if (force_dir_scan )
661
- arch_files_size = 0 ;
674
+ arch_files -> arch_files_size = 0 ;
662
675
663
676
/*
664
677
* If we still have stored file names from the previous directory scan,
665
678
* try to return one of those. We check to make sure the status file
666
679
* is still present, as the archive_command for a previous file may
667
680
* have already marked it done.
668
681
*/
669
- while (arch_files_size > 0 )
682
+ while (arch_files -> arch_files_size > 0 )
670
683
{
671
684
struct stat st ;
672
685
char status_file [MAXPGPATH ];
673
686
char * arch_file ;
674
687
675
- arch_files_size -- ;
676
- arch_file = arch_files [ arch_files_size ];
688
+ arch_files -> arch_files_size -- ;
689
+ arch_file = arch_files -> arch_files [ arch_files -> arch_files_size ];
677
690
StatusFilePath (status_file , arch_file , ".ready" );
678
691
679
692
if (stat (status_file , & st ) == 0 )
@@ -687,6 +700,9 @@ pgarch_readyXlog(char *xlog)
687
700
errmsg ("could not stat file \"%s\": %m" , status_file )));
688
701
}
689
702
703
+ /* arch_heap is probably empty, but let's make sure */
704
+ binaryheap_reset (arch_files -> arch_heap );
705
+
690
706
/*
691
707
* Open the archive status directory and read through the list of files
692
708
* with the .ready suffix, looking for the earliest files.
@@ -720,53 +736,53 @@ pgarch_readyXlog(char *xlog)
720
736
/*
721
737
* Store the file in our max-heap if it has a high enough priority.
722
738
*/
723
- if (arch_heap -> bh_size < NUM_FILES_PER_DIRECTORY_SCAN )
739
+ if (arch_files -> arch_heap -> bh_size < NUM_FILES_PER_DIRECTORY_SCAN )
724
740
{
725
741
/* If the heap isn't full yet, quickly add it. */
726
- arch_file = arch_filenames [arch_heap -> bh_size ];
742
+ arch_file = arch_files -> arch_filenames [arch_files -> arch_heap -> bh_size ];
727
743
strcpy (arch_file , basename );
728
- binaryheap_add_unordered (arch_heap , CStringGetDatum (arch_file ));
744
+ binaryheap_add_unordered (arch_files -> arch_heap , CStringGetDatum (arch_file ));
729
745
730
746
/* If we just filled the heap, make it a valid one. */
731
- if (arch_heap -> bh_size == NUM_FILES_PER_DIRECTORY_SCAN )
732
- binaryheap_build (arch_heap );
747
+ if (arch_files -> arch_heap -> bh_size == NUM_FILES_PER_DIRECTORY_SCAN )
748
+ binaryheap_build (arch_files -> arch_heap );
733
749
}
734
- else if (ready_file_comparator (binaryheap_first (arch_heap ),
750
+ else if (ready_file_comparator (binaryheap_first (arch_files -> arch_heap ),
735
751
CStringGetDatum (basename ), NULL ) > 0 )
736
752
{
737
753
/*
738
754
* Remove the lowest priority file and add the current one to
739
755
* the heap.
740
756
*/
741
- arch_file = DatumGetCString (binaryheap_remove_first (arch_heap ));
757
+ arch_file = DatumGetCString (binaryheap_remove_first (arch_files -> arch_heap ));
742
758
strcpy (arch_file , basename );
743
- binaryheap_add (arch_heap , CStringGetDatum (arch_file ));
759
+ binaryheap_add (arch_files -> arch_heap , CStringGetDatum (arch_file ));
744
760
}
745
761
}
746
762
FreeDir (rldir );
747
763
748
764
/* If no files were found, simply return. */
749
- if (arch_heap -> bh_size == 0 )
765
+ if (arch_files -> arch_heap -> bh_size == 0 )
750
766
return false;
751
767
752
768
/*
753
769
* If we didn't fill the heap, we didn't make it a valid one. Do that
754
770
* now.
755
771
*/
756
- if (arch_heap -> bh_size < NUM_FILES_PER_DIRECTORY_SCAN )
757
- binaryheap_build (arch_heap );
772
+ if (arch_files -> arch_heap -> bh_size < NUM_FILES_PER_DIRECTORY_SCAN )
773
+ binaryheap_build (arch_files -> arch_heap );
758
774
759
775
/*
760
776
* Fill arch_files array with the files to archive in ascending order
761
777
* of priority.
762
778
*/
763
- arch_files_size = arch_heap -> bh_size ;
764
- for (int i = 0 ; i < arch_files_size ; i ++ )
765
- arch_files [i ] = DatumGetCString (binaryheap_remove_first (arch_heap ));
779
+ arch_files -> arch_files_size = arch_files -> arch_heap -> bh_size ;
780
+ for (int i = 0 ; i < arch_files -> arch_files_size ; i ++ )
781
+ arch_files -> arch_files [i ] = DatumGetCString (binaryheap_remove_first (arch_files -> arch_heap ));
766
782
767
783
/* Return the highest priority file. */
768
- arch_files_size -- ;
769
- strcpy (xlog , arch_files [ arch_files_size ]);
784
+ arch_files -> arch_files_size -- ;
785
+ strcpy (xlog , arch_files -> arch_files [ arch_files -> arch_files_size ]);
770
786
771
787
return true;
772
788
}
0 commit comments