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

Commit1fb17b1

Browse files
committed
Fix issues in pgarch's new directory-scanning logic.
The arch_filenames[] array elements were one byte too small, so thata maximum-length filename would get corrupted if another entrywere made after it. (Noted by Thomas Munro, fix by Nathan Bossart.)Move these arrays into a palloc'd struct, so that we aren't wastinga few kilobytes of static data in each non-archiver process.Add a binaryheap_reset() call to make it plain that we start thedirectory scan with an empty heap. I don't think there's any livebug of that sort, but it seems fragile, and this is very cheapinsurance.Cleanup for commitbeb4e9b, so no back-patch needed.Discussion:https://postgr.es/m/CA+hUKGLHAjHuKuwtzsW7uMJF4BVPcQRL-UMZG_HM-g0y7yLkUg@mail.gmail.com
1 parent113fa39 commit1fb17b1

File tree

1 file changed

+43
-27
lines changed

1 file changed

+43
-27
lines changed

‎src/backend/postmaster/pgarch.c‎

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,20 @@ static PgArchData *PgArch = NULL;
111111
* completes, the file names are stored in ascending order of priority in
112112
* arch_files. pgarch_readyXlog() returns files from arch_files until it
113113
* 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.
114117
*/
115-
staticbinaryheap*arch_heap=NULL;
116-
staticchararch_filenames[NUM_FILES_PER_DIRECTORY_SCAN][MAX_XFN_CHARS];
117-
staticchar*arch_files[NUM_FILES_PER_DIRECTORY_SCAN];
118-
staticintarch_files_size=0;
118+
structarch_files_state
119+
{
120+
binaryheap*arch_heap;
121+
intarch_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+
chararch_filenames[NUM_FILES_PER_DIRECTORY_SCAN][MAX_XFN_CHARS+1];
125+
};
126+
127+
staticstructarch_files_state*arch_files=NULL;
119128

120129
/*
121130
* Flags set by interrupt handlers for later service in the main loop.
@@ -231,9 +240,13 @@ PgArchiverMain(void)
231240
*/
232241
PgArch->pgprocno=MyProc->pgprocno;
233242

243+
/* Create workspace for pgarch_readyXlog() */
244+
arch_files=palloc(sizeof(structarch_files_state));
245+
arch_files->arch_files_size=0;
246+
234247
/* 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);
237250

238251
pgarch_MainLoop();
239252

@@ -363,7 +376,7 @@ pgarch_ArchiverCopyLoop(void)
363376
charxlog[MAX_XFN_CHARS+1];
364377

365378
/* force directory scan in the first call to pgarch_readyXlog() */
366-
arch_files_size=0;
379+
arch_files->arch_files_size=0;
367380

368381
/*
369382
* loop through all xlogs with archive_status of .ready and archive
@@ -658,22 +671,22 @@ pgarch_readyXlog(char *xlog)
658671
SpinLockRelease(&PgArch->arch_lck);
659672

660673
if (force_dir_scan)
661-
arch_files_size=0;
674+
arch_files->arch_files_size=0;
662675

663676
/*
664677
* If we still have stored file names from the previous directory scan,
665678
* try to return one of those. We check to make sure the status file
666679
* is still present, as the archive_command for a previous file may
667680
* have already marked it done.
668681
*/
669-
while (arch_files_size>0)
682+
while (arch_files->arch_files_size>0)
670683
{
671684
structstatst;
672685
charstatus_file[MAXPGPATH];
673686
char*arch_file;
674687

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];
677690
StatusFilePath(status_file,arch_file,".ready");
678691

679692
if (stat(status_file,&st)==0)
@@ -687,6 +700,9 @@ pgarch_readyXlog(char *xlog)
687700
errmsg("could not stat file \"%s\": %m",status_file)));
688701
}
689702

703+
/* arch_heap is probably empty, but let's make sure */
704+
binaryheap_reset(arch_files->arch_heap);
705+
690706
/*
691707
* Open the archive status directory and read through the list of files
692708
* with the .ready suffix, looking for the earliest files.
@@ -720,53 +736,53 @@ pgarch_readyXlog(char *xlog)
720736
/*
721737
* Store the file in our max-heap if it has a high enough priority.
722738
*/
723-
if (arch_heap->bh_size<NUM_FILES_PER_DIRECTORY_SCAN)
739+
if (arch_files->arch_heap->bh_size<NUM_FILES_PER_DIRECTORY_SCAN)
724740
{
725741
/* 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];
727743
strcpy(arch_file,basename);
728-
binaryheap_add_unordered(arch_heap,CStringGetDatum(arch_file));
744+
binaryheap_add_unordered(arch_files->arch_heap,CStringGetDatum(arch_file));
729745

730746
/* 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);
733749
}
734-
elseif (ready_file_comparator(binaryheap_first(arch_heap),
750+
elseif (ready_file_comparator(binaryheap_first(arch_files->arch_heap),
735751
CStringGetDatum(basename),NULL)>0)
736752
{
737753
/*
738754
* Remove the lowest priority file and add the current one to
739755
* the heap.
740756
*/
741-
arch_file=DatumGetCString(binaryheap_remove_first(arch_heap));
757+
arch_file=DatumGetCString(binaryheap_remove_first(arch_files->arch_heap));
742758
strcpy(arch_file,basename);
743-
binaryheap_add(arch_heap,CStringGetDatum(arch_file));
759+
binaryheap_add(arch_files->arch_heap,CStringGetDatum(arch_file));
744760
}
745761
}
746762
FreeDir(rldir);
747763

748764
/* If no files were found, simply return. */
749-
if (arch_heap->bh_size==0)
765+
if (arch_files->arch_heap->bh_size==0)
750766
return false;
751767

752768
/*
753769
* If we didn't fill the heap, we didn't make it a valid one. Do that
754770
* now.
755771
*/
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);
758774

759775
/*
760776
* Fill arch_files array with the files to archive in ascending order
761777
* of priority.
762778
*/
763-
arch_files_size=arch_heap->bh_size;
764-
for (inti=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 (inti=0;i<arch_files->arch_files_size;i++)
781+
arch_files->arch_files[i]=DatumGetCString(binaryheap_remove_first(arch_files->arch_heap));
766782

767783
/* 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]);
770786

771787
return true;
772788
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp