Обсуждение: Allow pg_archivecleanup to remove backup history files
Hi, Currently pg_archivecleanup doesn't remove backup history files even when they're older than oldestkeptwalfile. Of course the size of backup history files are smaller than WAL files and they wouldn't consume much disk space, but a lot of backup history files(e.g. daily backup for years) whose backups data have been already removed are unnecessary and I would appreciate if pg_archivecleanup has an option to remove them. Attached a PoC patch, which added new option -b to remove files including backup history files older than oldestkeptwalfile. $ ls archivedir 000000010000000000000001 000000010000000000000003 000000010000000000000006 000000010000000000000008 000000010000000000000002 000000010000000000000004 000000010000000000000007 000000010000000000000009 000000010000000000000002.00000028.backup 000000010000000000000005 000000010000000000000007.00000028.backup 00000001000000000000000A.partial $ pg_archivecleanup -b archivedir 000000010000000000000009 $ ls archivedir 000000010000000000000009 00000001000000000000000A.partial Any thoughts? -- Regards, -- Atsushi Torikoshi NTT DATA CORPORATION
Вложения
At Tue, 25 Apr 2023 16:38:16 +0900, torikoshia <torikoshia@oss.nttdata.com> wrote in > Hi, > > Currently pg_archivecleanup doesn't remove backup history files even > when they're older than oldestkeptwalfile. > > Of course the size of backup history files are smaller than WAL files > and they wouldn't consume much disk space, but a lot of backup history > files(e.g. daily backup for years) whose backups data have been > already removed are unnecessary and I would appreciate if > pg_archivecleanup has an option to remove them. > > Attached a PoC patch, which added new option -b to remove files > including backup history files older than oldestkeptwalfile. > > $ ls archivedir > 000000010000000000000001 000000010000000000000003 > 000000010000000000000006 > 000000010000000000000008 > 000000010000000000000002 000000010000000000000004 > 000000010000000000000007 > 000000010000000000000009 > 000000010000000000000002.00000028.backup 000000010000000000000005 > 000000010000000000000007.00000028.backup > 00000001000000000000000A.partial > > $ pg_archivecleanup -b archivedir 000000010000000000000009 > > $ ls archivedir > 000000010000000000000009 00000001000000000000000A.partial > > Any thoughts? I thought that we have decided not to do that, but I coundn't find any discussion about it in the ML archive. Anyway, I think it is great that we have that option. regards. -- Kyotaro Horiguchi NTT Open Source Software Center
On Tue, Apr 25, 2023 at 05:29:48PM +0900, Kyotaro Horiguchi wrote: > I thought that we have decided not to do that, but I coundn't find any > discussion about it in the ML archive. Anyway, I think it is great > that we have that option. No objections from here to make that optional. It's been argued for a couple of times that leaving the archive history files is good for debugging, but I can also get why one would one to clean up all the files older than a WAL retention policy. Even if these are just few bytes, it can be noisy for the eye to see a large accumulation of history files mixed with the WAL segments. -- Michael
Вложения
Horiguchi-san, Michael-san Thanks for your comments and information! Attached a patch with documentation and regression tests. On 2023-04-26 06:39, Michael Paquier wrote: > On Tue, Apr 25, 2023 at 05:29:48PM +0900, Kyotaro Horiguchi wrote: >> I thought that we have decided not to do that, but I coundn't find any >> discussion about it in the ML archive. Anyway, I think it is great >> that we have that option. > > No objections from here to make that optional. It's been argued for a > couple of times that leaving the archive history files is good for > debugging, but I can also get why one would one to clean up all the > files older than a WAL retention policy. Even if these are just few > bytes, it can be noisy for the eye to see a large accumulation of > history files mixed with the WAL segments. > -- > Michael -- Regards, -- Atsushi Torikoshi NTT DATA CORPORATION
Вложения
On Tue, May 9, 2023 at 7:03 PM torikoshia <torikoshia@oss.nttdata.com> wrote: > > Attached a patch with documentation and regression tests. Thanks. I think pg_archivecleanup cleaning up history files makes it a complete feature as there's no need to write custom code/scripts over and above what pg_archivecleanup provides. It will help those who are using pg_archivecleanup for cleaning up older WAL files, say from their archive location. Just curious to know the driving point behind this proposal - is pg_archivecleanup deployed in production that was unable to clean up the history files and there were many such history files left? It will help us know how pg_archivecleanup is being used. I'm wondering if making -x generic with '-x' '.backup', is simpler than adding another option? Comments on the patch: 1. Why just only the backup history files? Why not remove the timeline history files too? Is it because there may not be as many tli switches happening as backups? 2.+sub remove_backuphistoryfile_run_check +{ Why to invent a new function when run_check() can be made generic with few arguments passed? For instance, run_check() can receive pg_archivecleanup command args, what to use for create_files(), in the error condition if the pg_archivecleanup command args contain 'b', then use a different message "$test_name: first older WAL file was cleaned up" or "$test_name: first .backup file was cleaned up". Otherwise, just modify the messages to be: "$test_name: first older file %s was cleaned up", $files[0]); "$test_name: second older file %s was cleaned up", $files[1]); "$test_name: restart file %s was not cleaned up", $files[2]); "$test_name: newer file %s was not cleaned up", $files[3]); "$test_name: unrelated file %s was not cleaned up", $files[4]); -- Bharath Rupireddy PostgreSQL Contributors Team RDS Open Source Databases Amazon Web Services: https://aws.amazon.com
On 2023-05-10 17:52, Bharath Rupireddy wrote: Thanks for your comments! > Just curious to know the driving point behind this proposal - is > pg_archivecleanup deployed in production that was unable to clean up > the history files and there were many such history files left? It will > help us know how pg_archivecleanup is being used. Yes. > Just curious to know the driving point behind this proposal - is > pg_archivecleanup deployed in production that was unable to clean up > the history files and there were many such history files left? It will > help us know how pg_archivecleanup is being used. > > I'm wondering if making -x generic with '-x' '.backup', is simpler > than adding another option? Since according to the current semantics, deleting backup history files with -x demands not '-x .backup' but '-x .007C9330.backup' when the file name is 0000000100001234000055CD.007C9330.backup, it needs special treatment for backup history files, right? I think it would be intuitive and easier to remember than new option. I was a little concerned about what to do when deleting both the files ending in .gz and backup history files. Is making it possible to specify both "-x .backup" and "-x .gz" the way to go? I also concerned someone might add ".backup" to WAL files, but does that usually not happen? > Comments on the patch: > 1. Why just only the backup history files? Why not remove the timeline > history files too? Is it because there may not be as many tli switches > happening as backups? Yeah, do you think we should also add logic for '-x .history'? > 2.+sub remove_backuphistoryfile_run_check > +{ > Why to invent a new function when run_check() can be made generic with > few arguments passed? Thanks, I'm going to reconsider it. -- Regards, -- Atsushi Torikoshi NTT DATA CORPORATION
On Fri, May 12, 2023 at 05:53:45PM +0900, torikoshia wrote: > On 2023-05-10 17:52, Bharath Rupireddy wrote: > I was a little concerned about what to do when deleting both the files > ending in .gz and backup history files. > Is making it possible to specify both "-x .backup" and "-x .gz" the way to > go? > > I also concerned someone might add ".backup" to WAL files, but does that > usually not happen? Depends on the archive command, of course. I have seen code using this suffix for some segment names in the past, FWIW. >> Comments on the patch: >> 1. Why just only the backup history files? Why not remove the timeline >> history files too? Is it because there may not be as many tli switches >> happening as backups? > > Yeah, do you think we should also add logic for '-x .history'? Timeline history files can be critical pieces when it comes to assigning a TLI as these could be retrieved by a restore_command during recovery for a TLI jump or just assign a new TLI number at the end of recovery, still you could presumably remove the TLI history files that are older than the TLI the segment defined refers too. (pg_archivecleanup has no specific logic to look at the history with child TLIs for example, to keep it simple, and I'd rather keep it this way). There may be an argument for making that optional, of course, but it does not strike me as really necessary compared to the backup history files which are just around for debugging purposes. >> 2.+sub remove_backuphistoryfile_run_check >> +{ >> Why to invent a new function when run_check() can be made generic with >> few arguments passed? > > Thanks, I'm going to reconsider it. + <para> + Remove files including backup history files, whose suffix is <filename>.backup</filename>. + Note that when <replaceable>oldestkeptwalfile</replaceable> is a backup history file, + specified file is kept and only preceding WAL files and backup history files are removed. + </para> This addition to the documentation looks unprecise to me. Backup history files have a more complex format than just the .backup suffix, and this is documented in backup.sgml. How about plugging in some long options, and use something more explicit like --clean-backup-history? - if ((IsXLogFileName(walfile) || IsPartialXLogFileName(walfile)) && + if (((IsXLogFileName(walfile) || IsPartialXLogFileName(walfile)) || + (removeBackupHistoryFile && IsBackupHistoryFileName(walfile))) && strcmp(walfile + 8, exclusiveCleanupFileName + 8) < 0) Could it be a bit cleaner to split this check in two, saving one level of indentation on the way for its most inner loop? I would imagine something like: /* Check file name */ if (!IsXLogFileName(walfile) && !IsPartialXLogFileName(walfile)) continue; /* Check cutoff point */ if (strcmp(walfile + 8, exclusiveCleanupFileName + 8) >= 0) continue; //rest of the code doing the unlinks. -- Michael
Вложения
On 2023-05-15 09:18, Michael Paquier wrote: > On Fri, May 12, 2023 at 05:53:45PM +0900, torikoshia wrote: >> On 2023-05-10 17:52, Bharath Rupireddy wrote: >> I was a little concerned about what to do when deleting both the files >> ending in .gz and backup history files. >> Is making it possible to specify both "-x .backup" and "-x .gz" the >> way to >> go? >> >> I also concerned someone might add ".backup" to WAL files, but does >> that >> usually not happen? > > Depends on the archive command, of course. I have seen code using > this suffix for some segment names in the past, FWIW. Thanks for the information. I'm going to stop adding special logic for "-x .backup" and add a new option for removing backup history files. >>> Comments on the patch: >>> 1. Why just only the backup history files? Why not remove the >>> timeline >>> history files too? Is it because there may not be as many tli >>> switches >>> happening as backups? >> >> Yeah, do you think we should also add logic for '-x .history'? > > Timeline history files can be critical pieces when it comes to > assigning a TLI as these could be retrieved by a restore_command > during recovery for a TLI jump or just assign a new TLI number at the > end of recovery, still you could presumably remove the TLI history > files that are older than the TLI the segment defined refers too. > (pg_archivecleanup has no specific logic to look at the history with > child TLIs for example, to keep it simple, and I'd rather keep it this > way). There may be an argument for making that optional, of course, > but it does not strike me as really necessary compared to the backup > history files which are just around for debugging purposes. Agreed. >>> 2.+sub remove_backuphistoryfile_run_check >>> +{ >>> Why to invent a new function when run_check() can be made generic >>> with >>> few arguments passed? >> >> Thanks, I'm going to reconsider it. > > + <para> > + Remove files including backup history files, whose suffix is > <filename>.backup</filename>. > + Note that when <replaceable>oldestkeptwalfile</replaceable> > is a backup history file, > + specified file is kept and only preceding WAL files and > backup history files are removed. > + </para> > > This addition to the documentation looks unprecise to me. Backup > history files have a more complex format than just the .backup > suffix, and this is documented in backup.sgml. I'm going to remove the explanation for the backup history files and just add the hyperlink to the original explanation in backup.sgml. > How about plugging in some long options, and use something more > explicit like --clean-backup-history? Agreed. > > - if ((IsXLogFileName(walfile) || IsPartialXLogFileName(walfile)) && > + if (((IsXLogFileName(walfile) || IsPartialXLogFileName(walfile)) || > + (removeBackupHistoryFile && > IsBackupHistoryFileName(walfile))) && > strcmp(walfile + 8, exclusiveCleanupFileName + 8) < 0) > > Could it be a bit cleaner to split this check in two, saving one level > of indentation on the way for its most inner loop? I would imagine > something like: > /* Check file name */ > if (!IsXLogFileName(walfile) && > !IsPartialXLogFileName(walfile)) > continue; > /* Check cutoff point */ > if (strcmp(walfile + 8, exclusiveCleanupFileName + 8) >= 0) > continue; > //rest of the code doing the unlinks. > -- Thanks, that looks better. -- Regards, -- Atsushi Torikoshi NTT DATA CORPORATION
On Mon, May 15, 2023 at 03:16:46PM +0900, torikoshia wrote: > On 2023-05-15 09:18, Michael Paquier wrote: >> How about plugging in some long options, and use something more >> explicit like --clean-backup-history? > > Agreed. If you begin to implement that, it seems to me that this should be shaped with a first separate patch that refactors the code to use getopt_long(), and a second patch for the proposed feature that builds on top of it. -- Michael
Вложения
On 2023-05-15 15:22, Michael Paquier wrote: > On Mon, May 15, 2023 at 03:16:46PM +0900, torikoshia wrote: >> On 2023-05-15 09:18, Michael Paquier wrote: >>> How about plugging in some long options, and use something more >>> explicit like --clean-backup-history? >> >> Agreed. > > If you begin to implement that, it seems to me that this should be > shaped with a first separate patch that refactors the code to use > getopt_long(), and a second patch for the proposed feature that builds > on top of it. Thanks for your advice, attached patches. -- Regards, -- Atsushi Torikoshi NTT DATA CORPORATION
Вложения
On Mon, May 22, 2023 at 06:24:49PM +0900, torikoshia wrote: > Thanks for your advice, attached patches. 0001 looks OK, thanks! + Remove files including backup history file. This could be reworded as "Remove backup history files.", I assume. + Note that when <replaceable>oldestkeptwalfile</replaceable> is a backup history file, + specified file is kept and only preceding WAL files and backup history files are removed. The same thing is described at the bottom of the documentation, so it does not seem necessary here. - printf(_(" -d, --debug generate debug output (verbose mode)\n")); - printf(_(" -n, --dry-run dry run, show the names of the files that would be removed\n")); - printf(_(" -V, --version output version information, then exit\n")); - printf(_(" -x --strip-extension=EXT clean up files if they have this extension\n")); - printf(_(" -?, --help show this help, then exit\n")); + printf(_(" -d, --debug generate debug output (verbose mode)\n")); + printf(_(" -n, --dry-run dry run, show the names of the files that would be removed\n")); + printf(_(" -b, --clean-backup-history clean up files including backup history files\n")); + printf(_(" -V, --version output version information, then exit\n")); + printf(_(" -x --strip-extension=EXT clean up files if they have this extension\n")); + printf(_(" -?, --help show this help, then exit\n")); Perhaps this indentation had better be adjusted in 0001, no big deal either way. - ok(!-f "$tempdir/$walfiles[0]", - "$test_name: first older WAL file was cleaned up"); + if (grep {$_ eq '-x.gz'} @options) { + ok(!-f "$tempdir/$walfiles[0]", + "$test_name: first older WAL file with .gz was cleaned up"); + } else { + ok(-f "$tempdir/$walfiles[0]", + "$test_name: first older WAL file with .gz was not cleaned up"); + } [...] - ok(-f "$tempdir/$walfiles[2]", - "$test_name: restartfile was not cleaned up"); + if (grep {$_ eq '-b'} @options) { + ok(!-f "$tempdir/$walfiles[2]", + "$test_name: Backup history file was cleaned up"); + } else { + ok(-f "$tempdir/$walfiles[2]", + "$test_name: Backup history file was not cleaned up"); + } That's over-complicated, caused by the fact that all the tests rely on the same list of WAL files to create, aka @walfiles defined at the beginning of the script. Wouldn't it be cleaner to handle the fake file creations with more than one global list, before each command run? The list of files to be created could just be passed down as an argument of run_check(), for example, before cleaning up the contents for the next command. -- Michael
Вложения
On 2023-05-24 10:26, Michael Paquier wrote: > On Mon, May 22, 2023 at 06:24:49PM +0900, torikoshia wrote: >> Thanks for your advice, attached patches. > > 0001 looks OK, thanks! > > + Remove files including backup history file. > > This could be reworded as "Remove backup history files.", I assume. > > + Note that when <replaceable>oldestkeptwalfile</replaceable> > is a backup history file, > + specified file is kept and only preceding WAL files and > backup history files are removed. > > The same thing is described at the bottom of the documentation, so it > does not seem necessary here. > > - printf(_(" -d, --debug generate debug output > (verbose mode)\n")); > - printf(_(" -n, --dry-run dry run, show the names > of the files that would be removed\n")); > - printf(_(" -V, --version output version > information, then exit\n")); > - printf(_(" -x --strip-extension=EXT clean up files if they > have this extension\n")); > - printf(_(" -?, --help show this help, then > exit\n")); > + printf(_(" -d, --debug generate debug output > (verbose mode)\n")); > + printf(_(" -n, --dry-run dry run, show the > names of the files that would be removed\n")); > + printf(_(" -b, --clean-backup-history clean up files > including backup history files\n")); > + printf(_(" -V, --version output version > information, then exit\n")); > + printf(_(" -x --strip-extension=EXT clean up files if they > have this extension\n")); > + printf(_(" -?, --help show this help, then > exit\n")); > > Perhaps this indentation had better be adjusted in 0001, no big deal > either way. > > - ok(!-f "$tempdir/$walfiles[0]", > - "$test_name: first older WAL file was cleaned up"); > + if (grep {$_ eq '-x.gz'} @options) { > + ok(!-f "$tempdir/$walfiles[0]", > + "$test_name: first older WAL file with .gz was > cleaned up"); > + } else { > + ok(-f "$tempdir/$walfiles[0]", > + "$test_name: first older WAL file with .gz was > not cleaned up"); > + } > [...] > - ok(-f "$tempdir/$walfiles[2]", > - "$test_name: restartfile was not cleaned up"); > + if (grep {$_ eq '-b'} @options) { > + ok(!-f "$tempdir/$walfiles[2]", > + "$test_name: Backup history file was cleaned > up"); > + } else { > + ok(-f "$tempdir/$walfiles[2]", > + "$test_name: Backup history file was not > cleaned up"); > + } > > That's over-complicated, caused by the fact that all the tests rely on > the same list of WAL files to create, aka @walfiles defined at the > beginning of the script. Wouldn't it be cleaner to handle the fake > file creations with more than one global list, before each command > run? The list of files to be created could just be passed down as an > argument of run_check(), for example, before cleaning up the contents > for the next command. > -- > Michael Thanks for reviewing! Updated patches according to your comment. -- Regards, -- Atsushi Torikoshi NTT DATA CORPORATION
Вложения
At Thu, 25 May 2023 23:51:18 +0900, torikoshia <torikoshia@oss.nttdata.com> wrote in > Updated patches according to your comment. + printf(_(" -x --strip-extension=EXT clean up files if they have this extension\n")); Perhaps a comma is needed after "-x". The apparent inconsistency between the long name and the description is perplexing. I think it might be more suitable to reword the descrition to "ignore this extension while identifying files for cleanup" or something along those lines..., and then name the option as "--ignore-extension". The patch leaves the code. > * Truncation is essentially harmless, because we skip names of > * length other than XLOG_FNAME_LEN. (In principle, one could use > * a 1000-character additional_ext and get trouble.) > */ > strlcpy(walfile, xlde->d_name, MAXPGPATH); > TrimExtension(walfile, additional_ext); The comment is no longer correct about the file name length. + if (!IsXLogFileName(walfile) && !IsPartialXLogFileName(walfile) && + (!cleanBackupHistory || !IsBackupHistoryFileName(walfile))) + continue; I'm not certain about the others, but I see this a tad tricky to understand at first glance. Here's how I would phrase it. (A nearby comment might require a tweak if we go ahead with this change.) if (!(IsXLogFileName(walfile) || IsPartialXLogFileName(walfile) || (cleanBackupHistory && IsBackupHistoryFileName(walfile)))) or if (!IsXLogFileName(walfile) && !IsPartialXLogFileName(walfile) && !(cleanBackupHistory && IsBackupHistoryFileName(walfile))) By the way, this patch reduces the nesting level. If we go that direction, the following structure could be reworked similarly, and I believe it results in a more standard structure. if ((xldir = opendir(archiveLocation)) != NULL) { ... } else pg_fatal("could not open archive location.. regards. -- Kyotaro Horiguchi NTT Open Source Software Center
On Fri, May 26, 2023 at 10:07:48AM +0900, Kyotaro Horiguchi wrote: > + if (!IsXLogFileName(walfile) && !IsPartialXLogFileName(walfile) && > + (!cleanBackupHistory || !IsBackupHistoryFileName(walfile))) > + continue; > > I'm not certain about the others, but I see this a tad tricky to > understand at first glance. Here's how I would phrase it. (A nearby > comment might require a tweak if we go ahead with this change.) > > if (!(IsXLogFileName(walfile) || IsPartialXLogFileName(walfile) || > (cleanBackupHistory && IsBackupHistoryFileName(walfile)))) > or > if (!IsXLogFileName(walfile) && !IsPartialXLogFileName(walfile) && > !(cleanBackupHistory && IsBackupHistoryFileName(walfile))) FWIW, I am OK with what's written in the patch, but it is true that your second suggestion makes things a bit easier to read, perhaps. -- Michael
Вложения
On Thu, May 25, 2023 at 11:51:18PM +0900, torikoshia wrote: > Updated patches according to your comment. - ok(!-f "$tempdir/$walfiles[1]", - "$test_name: second older WAL file was cleaned up"); - ok(-f "$tempdir/$walfiles[2]", + ok(!-f "$tempdir/@$walfiles[1]", + "$test_name: second older WAL/backup history file was cleaned up"); + ok(-f "$tempdir/@$walfiles[2]", This is still a bit confusing, because as designed the test has a dependency on the number of elements present in the list, and the description of the test may not refer to what's actually used (the second element of each list is either a WAL segment or a backup history file). I think that I would just rewrite that so as we have a list of WAL segments in an array with the expected result associated to each one of them. Basically, something like that: my @wal_segments = ( { name => "SEGMENT1", present => 0 }, { name => "BACKUPFILE1", present => 1 }, { name => "SEGMENT2", present => 0 }); Then the last part of run_check() would loop through all the elements listed. -- Michael
Вложения
On 2023-05-26 10:07, Kyotaro Horiguchi wrote: Thanks for your review! > + printf(_(" -x --strip-extension=EXT clean up files if they have > this extension\n")); > > Perhaps a comma is needed after "-x". That's an oversight. Modified it. > The apparent inconsistency > between the long name and the description is perplexing. I think it > might be more suitable to reword the descrition to "ignore this > extension while identifying files for cleanup" or something along > those lines..., and then name the option as "--ignore-extension". I used 'strip' since it is used in the manual as below: | -x extension | Provide an extension that will be stripped from all file names before deciding if they should be deleted I think using the same verb both in long name option and in the manual is natural. How about something like this? | printf(_(" -x, --strip-extension=EXT strip this extention before identifying files fo clean up\n")); > The patch leaves the code. > >> * Truncation is essentially harmless, because we skip names of >> * length other than XLOG_FNAME_LEN. (In principle, one could use >> * a 1000-character additional_ext and get trouble.) >> */ >> strlcpy(walfile, xlde->d_name, MAXPGPATH); >> TrimExtension(walfile, additional_ext); > > The comment is no longer correct about the file name length. Yeah. considering parital WAL, it would be not correct even before applying the patch. I modifiied the comments as below: | * Truncation is essentially harmless, because we check the file | * format including the length immediately after this. > + if (!IsXLogFileName(walfile) && !IsPartialXLogFileName(walfile) && > + (!cleanBackupHistory || !IsBackupHistoryFileName(walfile))) > + continue; > > I'm not certain about the others, but I see this a tad tricky to > understand at first glance. Here's how I would phrase it. (A nearby > comment might require a tweak if we go ahead with this change.) > > if (!(IsXLogFileName(walfile) || IsPartialXLogFileName(walfile) || > (cleanBackupHistory && IsBackupHistoryFileName(walfile)))) > > or > > if (!IsXLogFileName(walfile) && !IsPartialXLogFileName(walfile) && > !(cleanBackupHistory && IsBackupHistoryFileName(walfile))) Thanks for the suggestion, I used the second one. > By the way, this patch reduces the nesting level. If we go that > direction, the following structure could be reworked similarly, and I > believe it results in a more standard structure. > > if ((xldir = opendir(archiveLocation)) != NULL) > { > ... > } > else > pg_fatal("could not open archive location.. Agreed. Attached 0003 patch for this. On 2023-05-26 14:19, Michael Paquier wrote: > On Thu, May 25, 2023 at 11:51:18PM +0900, torikoshia wrote: >> Updated patches according to your comment. > > - ok(!-f "$tempdir/$walfiles[1]", > - "$test_name: second older WAL file was cleaned up"); > - ok(-f "$tempdir/$walfiles[2]", > + ok(!-f "$tempdir/@$walfiles[1]", > + "$test_name: second older WAL/backup history file was cleaned > up"); > + ok(-f "$tempdir/@$walfiles[2]", > > This is still a bit confusing, because as designed the test has a > dependency on the number of elements present in the list, and the > description of the test may not refer to what's actually used (the > second element of each list is either a WAL segment or a backup > history file). I think that I would just rewrite that so as we have a > list of WAL segments in an array with the expected result associated > to each one of them. Basically, something like that: > my @wal_segments = ( > { name => "SEGMENT1", present => 0 }, > { name => "BACKUPFILE1", present => 1 }, > { name => "SEGMENT2", present => 0 }); > > Then the last part of run_check() would loop through all the elements > listed. Thanks. Update the patch according to the advice. I also changed the parameter of run_check() from specifying extension of oldestkeptwalfile to oldestkeptwalfile itself. -- Regards, -- Atsushi Torikoshi NTT DATA CORPORATION
Вложения
On 2023/05/31 10:51, torikoshia wrote: > Update the patch according to the advice. Thanks for updating the patches! I have small comments regarding 0002 patch. + <para> + Remove backup history files. Isn't it better to document clearly which backup history files to be removed? For example, "In addition to removing WAL files,remove backup history files with prefixes logically preceding the oldestkeptwalfile.". printf(_(" -n, --dry-run dry run, show the names of the files that would be removed\n")); + printf(_(" -b, --clean-backup-history clean up files including backup history files\n")); Shouldn't -b option be placed in alphabetical order? Regards, -- Fujii Masao Advanced Computing Technology Center Research and Development Headquarters NTT DATA CORPORATION
On Fri, Jun 09, 2023 at 12:32:15AM +0900, Fujii Masao wrote: > + <para> > + Remove backup history files. > > Isn't it better to document clearly which backup history files to be removed? For example, "In addition to removing WALfiles, remove backup history files with prefixes logically preceding the oldestkeptwalfile.". I've written about this part at the beginning of this one, where this sounds like a duplicated description of the Description section: https://www.postgresql.org/message-id/ZG1nq13v411y4TFL@paquier.xyz > printf(_(" -n, --dry-run dry run, show the names of the files that would be removed\n")); > + printf(_(" -b, --clean-backup-history clean up files including backup history files\n")); > > Shouldn't -b option be placed in alphabetical order? +1. -- Michael
Вложения
On 2023-06-12 16:33, Michael Paquier wrote: > On Fri, Jun 09, 2023 at 12:32:15AM +0900, Fujii Masao wrote: Thanks for reviewing! >> printf(_(" -n, --dry-run dry run, show the names of >> the files that would be removed\n")); >> + printf(_(" -b, --clean-backup-history clean up files including >> backup history files\n")); >> >> Shouldn't -b option be placed in alphabetical order? > > +1. Modified the place. -- Regards, -- Atsushi Torikoshi NTT DATA CORPORATION
Вложения
At Wed, 14 Jun 2023 00:49:39 +0900, torikoshia <torikoshia@oss.nttdata.com> wrote in > On 2023-06-12 16:33, Michael Paquier wrote: > > On Fri, Jun 09, 2023 at 12:32:15AM +0900, Fujii Masao wrote: > Thanks for reviewing! > > >> printf(_(" -n, --dry-run dry run, show the names of the files that > >> would be removed\n")); > >> + printf(_(" -b, --clean-backup-history clean up files including > >> backup history files\n")); > >> Shouldn't -b option be placed in alphabetical order? > > +1. > > Modified the place. - printf(_(" -d generate debug output (verbose mode)\n")); - printf(_(" -n dry run, show the names of the files that would be removed\n")); - printf(_(" -V, --version output version information, then exit\n")); - printf(_(" -x EXT clean up files if they have this extension\n")); - printf(_(" -?, --help show this help, then exit\n")); + printf(_(" -d, --debug generate debug output (verbose mode)\n")); + printf(_(" -n, --dry-run dry run, show the names of the files that would be removed\n")); + printf(_(" -V, --version output version information, then exit\n")); + printf(_(" -x, --strip-extension=EXT strip this extention before identifying files fo clean up\n")); + printf(_(" -?, --help show this help, then exit\n")); After this change, some of these lines corss the boundary of the 80 columns width. (is that policy viable noadays? I am usually working using terminal windows with such a width..) It's somewhat unrelated to this patch, but a help line a few lines further down also exceeds the width. We could shorten it by removing the "/mnt/server" portion, but I'm not sure if it's worth doing. > Or for use as a standalone archive cleaner: > e.g. > pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup + printf(_(" -x, --strip-extension=EXT strip this extention before identifying files fo clean up\n")); s/fo/for/ ? regards. -- Kyotaro Horiguchi NTT Open Source Software Center
On 2023-06-15 15:20, Kyotaro Horiguchi wrote: Thanks for your review! > At Wed, 14 Jun 2023 00:49:39 +0900, torikoshia > <torikoshia@oss.nttdata.com> wrote in >> On 2023-06-12 16:33, Michael Paquier wrote: >> > On Fri, Jun 09, 2023 at 12:32:15AM +0900, Fujii Masao wrote: >> Thanks for reviewing! >> >> >> printf(_(" -n, --dry-run dry run, show the names of the files that >> >> would be removed\n")); >> >> + printf(_(" -b, --clean-backup-history clean up files including >> >> backup history files\n")); >> >> Shouldn't -b option be placed in alphabetical order? >> > +1. >> >> Modified the place. > > - printf(_(" -d generate debug output (verbose mode)\n")); > - printf(_(" -n dry run, show the names of the files that > would be removed\n")); > - printf(_(" -V, --version output version information, then > exit\n")); > - printf(_(" -x EXT clean up files if they have this > extension\n")); > - printf(_(" -?, --help show this help, then exit\n")); > + printf(_(" -d, --debug generate debug output > (verbose mode)\n")); > + printf(_(" -n, --dry-run dry run, show the names of > the files that would be removed\n")); > + printf(_(" -V, --version output version information, > then exit\n")); > + printf(_(" -x, --strip-extension=EXT strip this extention before > identifying files fo clean up\n")); > + printf(_(" -?, --help show this help, then > exit\n")); > > After this change, some of these lines corss the boundary of the 80 > columns width. (is that policy viable noadays? I am usually working > using terminal windows with such a width..) It's somewhat unrelated to > this patch, but a help line a few lines further down also exceeds the > width. We could shorten it by removing the "/mnt/server" portion, but > I'm not sure if it's worth doing. I also highlight 80th column according to the wiki[1]. Since usage() in other files like pg_rewind.c and initdb.c also exceeded the 80th column, I thought that was something like a guide. >> Or for use as a standalone archive cleaner: >> e.g. >> pg_archivecleanup /mnt/server/archiverdir >> 000000010000000000000010.00000020.backup > > > + printf(_(" -x, --strip-extension=EXT strip this extention before > identifying files fo clean up\n")); > > s/fo/for/ ? Yeah, it's a typo. Fixed it. [1] https://wiki.postgresql.org/wiki/Configuring_vim_for_postgres_development -- Regards, -- Atsushi Torikoshi NTT DATA CORPORATION
Вложения
At Thu, 15 Jun 2023 21:38:28 +0900, torikoshia <torikoshia@oss.nttdata.com> wrote in > On 2023-06-15 15:20, Kyotaro Horiguchi wrote: > Thanks for your review! > > + printf(_(" -x, --strip-extension=EXT strip this extention before > > identifying files fo clean up\n")); > > + printf(_(" -?, --help show this help, then exit\n")); > > After this change, some of these lines corss the boundary of the 80 > > columns width. (is that policy viable noadays? I am usually working > > using terminal windows with such a width..) It's somewhat unrelated to > > this patch, but a help line a few lines further down also exceeds the > > width. We could shorten it by removing the "/mnt/server" portion, but > > I'm not sure if it's worth doing. > > I also highlight 80th column according to the wiki[1]. > Since usage() in other files like pg_rewind.c and initdb.c also > exceeded the 80th column, I thought that was something like a guide. I think the page is suggesting about program code, not the messages that binaries print. ASAICS the main section of the "pg_rewind --help" fits within 80 columns. However, "initdb --help" does output a few lines exceeding the 80-column limit. Judging by the surrounding lines, I believe we're still aiming to maintain these the given width. I think we need to fix initdb in that regard. > [1] > https://wiki.postgresql.org/wiki/Configuring_vim_for_postgres_development regards. -- Kyotaro Horiguchi NTT Open Source Software Center
At Fri, 16 Jun 2023 11:22:31 +0900 (JST), Kyotaro Horiguchi <horikyota.ntt@gmail.com> wrote in > ASAICS the main section of the "pg_rewind --help" fits within 80 > columns. However, "initdb --help" does output a few lines exceeding > the 80-column limit. Judging by the surrounding lines, I believe we're > still aiming to maintain these the given width. I think we need to fix > initdb in that regard. Mmm, the message was introduced in 2012 by 8a02339e9b. I haven't noticed this until now... regards. -- Kyotaro Horiguchi NTT Open Source Software Center
On 2023-06-16 11:22, Kyotaro Horiguchi wrote: > At Thu, 15 Jun 2023 21:38:28 +0900, torikoshia > <torikoshia@oss.nttdata.com> wrote in >> On 2023-06-15 15:20, Kyotaro Horiguchi wrote: >> Thanks for your review! >> > + printf(_(" -x, --strip-extension=EXT strip this extention before >> > identifying files fo clean up\n")); >> > + printf(_(" -?, --help show this help, then exit\n")); >> > After this change, some of these lines corss the boundary of the 80 >> > columns width. (is that policy viable noadays? I am usually working >> > using terminal windows with such a width..) It's somewhat unrelated to >> > this patch, but a help line a few lines further down also exceeds the >> > width. We could shorten it by removing the "/mnt/server" portion, but >> > I'm not sure if it's worth doing. >> >> I also highlight 80th column according to the wiki[1]. >> Since usage() in other files like pg_rewind.c and initdb.c also >> exceeded the 80th column, I thought that was something like a guide. > > I think the page is suggesting about program code, not the messages > that binaries print. Thanks, now I understand what you meant. > ASAICS the main section of the "pg_rewind --help" fits within 80 > columns. However, "initdb --help" does output a few lines exceeding > the 80-column limit. Judging by the surrounding lines, I believe we're > still aiming to maintain these the given width. I think we need to fix > initdb in that regard. Hmm, it seems some other commands also exceeds 80 columns: pg_amcheck: --skip=OPTION do NOT check "all-frozen" or "all-visible" blocks --startblock=BLOCK begin checking table(s) at the given block number --endblock=BLOCK check table(s) only up to the given block number --no-synchronized-snapshots do not use synchronized snapshots in parallel jobs pg_isready: -t, --timeout=SECS seconds to wait when attempting connection, 0 disables (default: 3) pg_receivewal: --create-slot create a new replication slot (for the slot's name see --slot) --drop-slot drop the replication slot (for the slot's name see --slot) If you don't mind, I'm going to create another thread about this point. I'll also discuss below line since it's unrelated to current thread as you pointed out: | pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup Attached patch fixes the number of columns per row exceeding 80 by changing to use getopt_long. On 2023-06-16 11:30, Kyotaro Horiguchi wrote: > At Fri, 16 Jun 2023 11:22:31 +0900 (JST), Kyotaro Horiguchi > <horikyota.ntt@gmail.com> wrote in >> ASAICS the main section of the "pg_rewind --help" fits within 80 >> columns. However, "initdb --help" does output a few lines exceeding >> the 80-column limit. Judging by the surrounding lines, I believe we're >> still aiming to maintain these the given width. I think we need to fix >> initdb in that regard. > > Mmm, the message was introduced in 2012 by 8a02339e9b. I haven't > noticed this until now... > > regards. -- Regards, -- Atsushi Torikoshi NTT DATA CORPORATION
Вложения
On Mon, Jun 19, 2023 at 11:24:29AM +0900, torikoshia wrote: > Thanks, now I understand what you meant. If I may ask, why is the refactoring of 0003 done after the feature in 0002? Shouldn't the order be reversed? That would make for a cleaner git history. -- Michael
Вложения
On 2023-06-19 14:37, Michael Paquier wrote: > On Mon, Jun 19, 2023 at 11:24:29AM +0900, torikoshia wrote: >> Thanks, now I understand what you meant. > > If I may ask, why is the refactoring of 0003 done after the feature in > 0002? Shouldn't the order be reversed? That would make for a cleaner > git history. > -- > Michael Agreed. Reversed the order of patches 0002 and 0003. -- Regards, -- Atsushi Torikoshi NTT DATA CORPORATION
Вложения
At Tue, 20 Jun 2023 22:27:36 +0900, torikoshia <torikoshia@oss.nttdata.com> wrote in > On 2023-06-19 14:37, Michael Paquier wrote: > > On Mon, Jun 19, 2023 at 11:24:29AM +0900, torikoshia wrote: > >> Thanks, now I understand what you meant. > > If I may ask, why is the refactoring of 0003 done after the feature in > > 0002? Shouldn't the order be reversed? That would make for a cleaner > > git history. > > -- > > Michael > > Agreed. > Reversed the order of patches 0002 and 0003. Yeah, that is a possible division. However, I meant that we have room to refactor and decrease the nesting level even further, considering that 0003 already does this to some extent, when I suggested it. In that sense, moving the nest-reduction part of 0003 into 0002 makes us possible to focus on the point of this patch. What do you think about the attached version? regards. -- Kyotaro Horiguchi NTT Open Source Software Center
Вложения
On 2023-06-21 11:59, Kyotaro Horiguchi wrote: > At Tue, 20 Jun 2023 22:27:36 +0900, torikoshia > <torikoshia@oss.nttdata.com> wrote in >> On 2023-06-19 14:37, Michael Paquier wrote: >> > On Mon, Jun 19, 2023 at 11:24:29AM +0900, torikoshia wrote: >> >> Thanks, now I understand what you meant. >> > If I may ask, why is the refactoring of 0003 done after the feature in >> > 0002? Shouldn't the order be reversed? That would make for a cleaner >> > git history. >> > -- >> > Michael >> >> Agreed. >> Reversed the order of patches 0002 and 0003. > > Yeah, that is a possible division. However, I meant that we have room > to refactor and decrease the nesting level even further, considering > that 0003 already does this to some extent, when I suggested it. In > that sense, moving the nest-reduction part of 0003 into 0002 makes us > possible to focus on the point of this patch. Thanks for the comment, it seems better than v9 patch. > What do you think about the attached version? --v10-0002-Preliminary-refactoring-for-a-subsequent-patch.patch + * Also we skip backup history files when --clean-backup-history + * is not specified. + */ + if (!IsXLogFileName(walfile) && !IsPartialXLogFileName(walfile)) + continue; I think this comment should be located in 0003. Attached updated patches. -- Regards, -- Atsushi Torikoshi NTT DATA CORPORATION
Вложения
At Wed, 21 Jun 2023 23:41:33 +0900, torikoshia <torikoshia@oss.nttdata.com> wrote in > --v10-0002-Preliminary-refactoring-for-a-subsequent-patch.patch > + * Also we skip backup history files when --clean-backup-history > + * is not specified. > + */ > + if (!IsXLogFileName(walfile) && !IsPartialXLogFileName(walfile)) > + continue; > > I think this comment should be located in 0003. Auch! Right. > Attached updated patches. Thanks! 0001: Looks good to me. 0002: + * Check file name. + * + * We skip files which are not WAL file or partial WAL file. There's no need to spend this many lines describing this, and it's suggested to avoid restating what the code does. I think a comment might not be necessary. But if we decide to have one, it could look like this: > /* we're only removing specific types of files */ Other than that, it looks good to me. 0003: + <para> + Remove backup history files. I might be overthinking it, but I'd phrase it as, "Remove backup history files *as well*.". (The --help message describes the same thing using "including".) + For details about backup history file, please refer to the <xref linkend="backup-base-backup"/>. We usually write this as simple as "See <xref...> for details (of the backup history files)" or "Refer to <xref..> for more information (about the backup history files)." or such like... (I think) +bool cleanBackupHistory = false; /* remove files including + * backup history files */ The indentation appears to be inconsistent. - * Truncation is essentially harmless, because we skip names of - * length other than XLOG_FNAME_LEN. (In principle, one could use - * a 1000-character additional_ext and get trouble.) + * Truncation is essentially harmless, because we check the file + * format including the length immediately after this. + * (In principle, one could use a 1000-character additional_ext + * and get trouble.) */ strlcpy(walfile, xlde->d_name, MAXPGPATH); TrimExtension(walfile, additional_ext); The revised comment seems to drift from the original point. Except for a potential exception by a too-long addition_ext, the original comment asserted that the name truncation was safe since it wouldn't affect the files we're removing. In other words, it asserted that the filenames to be removed won't be truncated and any actual truncation wouldn't lead to accidental deletions. Hence, I think we should adjust the comment to maintain its original point, and extend it to include backup history files. A possible revision could be (very simple): > * Truncation is essentially harmless, because we skip names of length > * longer than the length of backup history file. (In principle, one > * could use a 1000-character additional_ext and get trouble.) Regarding the TAP test, it checks that the --clean-backup-history does indeed remove backup history files. However, it doesn't check that this doesn't occur if the option isn't specified. Shouldn't we test for the latter scenario as well? +sub get_walfiles +{ <snip..> + +create_files(get_walfiles(@walfiles_with_gz)); The new function get_walfiels() just increases the line count without cutting any lines. The following changes are sufficient and easier to read (at least for me). > open my $file, '>', "$tempdir/$fn->{name}"; > foreach my $fn (map {$_->{name}} @walfiles_with_gz) regards. -- Kyotaro Horiguchi NTT Open Source Software Center
On 2023-06-22 16:47, Kyotaro Horiguchi wrote: Thanks for your review! > > 0002: > > + * Check file name. > + * > + * We skip files which are not WAL file or partial WAL file. > > There's no need to spend this many lines describing this, and it's > suggested to avoid restating what the code does. I think a comment > might not be necessary. But if we decide to have one, it could look > like this: > >> /* we're only removing specific types of files */ As you mentioned, this comment is restatement of the codes. Removed the comment. > > Other than that, it looks good to me. > > > 0003: > + <para> > + Remove backup history files. > > I might be overthinking it, but I'd phrase it as, "Remove backup > history files *as well*.". (The --help message describes the same > thing using "including".) Agreed. > + For details about backup history file, please refer to the > <xref linkend="backup-base-backup"/>. > > We usually write this as simple as "See <xref...> for details (of the > backup history files)" or "Refer to <xref..> for more information > (about the backup history files)." or such like... (I think) Agreed. I used the former one. > +bool cleanBackupHistory = false; /* remove files including > + * backup history files */ > > The indentation appears to be inconsistent. Modified. > > > - * Truncation is essentially harmless, because we skip names of > - * length other than XLOG_FNAME_LEN. (In principle, one could use > - * a 1000-character additional_ext and get trouble.) > + * Truncation is essentially harmless, because we check the file > + * format including the length immediately after this. > + * (In principle, one could use a 1000-character additional_ext > + * and get trouble.) > */ > strlcpy(walfile, xlde->d_name, MAXPGPATH); > TrimExtension(walfile, additional_ext); > > The revised comment seems to drift from the original point. Except for > a potential exception by a too-long addition_ext, the original comment > asserted that the name truncation was safe since it wouldn't affect > the files we're removing. In other words, it asserted that the > filenames to be removed won't be truncated and any actual truncation > wouldn't lead to accidental deletions. > > Hence, I think we should adjust the comment to maintain its original > point, and extend it to include backup history files. A possible > revision could be (very simple): > >> * Truncation is essentially harmless, because we skip names of >> length >> * longer than the length of backup history file. (In principle, one >> * could use a 1000-character additional_ext and get trouble.) This is true, but we do stricter check for preventing accidental deletion at the below code than just skipping "names of length longer than the length of backup history file". | if (!IsXLogFileName(walfile) && !IsPartialXLogFileName(walfile) && | !(cleanBackupHistory && IsBackupHistoryFileName(walfile))) | continue; How about something like this? | Truncation is essentially harmless, because we skip files whose format is different from WAL files and backup history files. > Regarding the TAP test, it checks that the --clean-backup-history does > indeed remove backup history files. However, it doesn't check that > this doesn't occur if the option isn't specified. Shouldn't we test > for the latter scenario as well? Agreed. Added a backup history file to @walfiles_with_gz. > +sub get_walfiles > +{ > <snip..> > + > +create_files(get_walfiles(@walfiles_with_gz)); > > The new function get_walfiels() just increases the line count without > cutting any lines. The following changes are sufficient and easier to > read (at least for me). > >> open my $file, '>', "$tempdir/$fn->{name}"; > >> foreach my $fn (map {$_->{name}} @walfiles_with_gz) Agreed. Remove get_walfiles() and added some changes as above. -- Regards, -- Atsushi Torikoshi NTT DATA CORPORATION
Вложения
On Fri, Jun 23, 2023 at 05:37:09PM +0900, torikoshia wrote: > On 2023-06-22 16:47, Kyotaro Horiguchi wrote: > Thanks for your review! I have begun cleaning up my board, and applied 0001 for the moment. -- Michael
Вложения
On Fri, Jun 30, 2023 at 03:48:43PM +0900, Michael Paquier wrote: > I have begun cleaning up my board, and applied 0001 for the moment. And a few weeks later.. I have come around this thread and applied 0002 and 0003. The flow of 0002 was straight-forward. My main issue was in 0003, actually, where the TAP tests were kind of confusing as written: - There was no cleanup of the files still present after a single command check, which could easily mess up the tests. - The --dry-run case was using the list of WAL files for the extension pattern checks, hardcoding names based on the position of its array. I have switched that to use a third list of files, instead. The result looked OK and that can be extended easily for more patterns or more commands, so applied 0003 after doing these adjustments, coupled with a pgperltidy run, a pgperlcritic check and an indentation. -- Michael
Вложения
On 2023-07-19 13:58, Michael Paquier wrote: > On Fri, Jun 30, 2023 at 03:48:43PM +0900, Michael Paquier wrote: >> I have begun cleaning up my board, and applied 0001 for the moment. > > And a few weeks later.. I have come around this thread and applied > 0002 and 0003. > > The flow of 0002 was straight-forward. My main issue was in 0003, > actually, where the TAP tests were kind of confusing as written: > - There was no cleanup of the files still present after a single > command check, which could easily mess up the tests. > - The --dry-run case was using the list of WAL files for the extension > pattern checks, hardcoding names based on the position of its array. > I have switched that to use a third list of files, instead. > > The result looked OK and that can be extended easily for more > patterns or more commands, so applied 0003 after doing these > adjustments, coupled with a pgperltidy run, a pgperlcritic check and > an indentation. > -- > Michael Thanks for the reviewing and applying the patches! -- Regards, -- Atsushi Torikoshi NTT DATA CORPORATION