not_create_histfile_if_not_arch_v1.patch

application/octet-stream

Filename: not_create_histfile_if_not_arch_v1.patch
Type: application/octet-stream
Part: 0
Message: Re: Allowing multiple concurrent base backups

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: context
Series: patch v1
File+
doc/src/sgml/backup.sgml 2 0
doc/src/sgml/func.sgml 2 0
src/backend/access/transam/xlog.c 44 0
*** a/doc/src/sgml/backup.sgml
--- b/doc/src/sgml/backup.sgml
***************
*** 874,880 **** SELECT pg_stop_backup();
     <para>
      To make use of the backup, you will need to keep all the WAL
      segment files generated during and after the file system backup.
!     To aid you in doing this, the <function>pg_stop_backup</> function
      creates a <firstterm>backup history file</> that is immediately
      stored into the WAL archive area. This file is named after the first
      WAL segment file that you need for the file system backup.
--- 874,881 ----
     <para>
      To make use of the backup, you will need to keep all the WAL
      segment files generated during and after the file system backup.
!     To aid you in doing this, if archiving is enabled,
!     the <function>pg_stop_backup</> function
      creates a <firstterm>backup history file</> that is immediately
      stored into the WAL archive area. This file is named after the first
      WAL segment file that you need for the file system backup.
*** a/doc/src/sgml/func.sgml
--- b/doc/src/sgml/func.sgml
***************
*** 14029,14035 **** postgres=# select pg_start_backup('label_goes_here');
     <para>
      <function>pg_stop_backup</> removes the label file created by
      <function>pg_start_backup</>, and creates a backup history file in
!     the transaction log archive area.  The history file includes the label given to
      <function>pg_start_backup</>, the starting and ending transaction log locations for
      the backup, and the starting and ending times of the backup.  The return
      value is the backup's ending transaction log location (which again
--- 14029,14036 ----
     <para>
      <function>pg_stop_backup</> removes the label file created by
      <function>pg_start_backup</>, and creates a backup history file in
!     the transaction log archive area if archiving is enabled.
!     The history file includes the label given to
      <function>pg_start_backup</>, the starting and ending transaction log locations for
      the backup, and the starting and ending times of the backup.  The return
      value is the backup's ending transaction log location (which again
*** a/src/backend/access/transam/xlog.c
--- b/src/backend/access/transam/xlog.c
***************
*** 8636,8652 **** do_pg_stop_backup(char *labelfile)
  	XLogRecPtr	startpoint;
  	XLogRecPtr	stoppoint;
  	XLogRecData rdata;
- 	pg_time_t	stamp_time;
- 	char		strfbuf[128];
- 	char		histfilepath[MAXPGPATH];
  	char		startxlogfilename[MAXFNAMELEN];
- 	char		stopxlogfilename[MAXFNAMELEN];
  	char		lastxlogfilename[MAXFNAMELEN];
  	char		histfilename[MAXFNAMELEN];
  	uint32		_logId;
  	uint32		_logSeg;
  	FILE	   *lfp;
- 	FILE	   *fp;
  	char		ch;
  	int			seconds_before_warning;
  	int			waits = 0;
--- 8636,8647 ----
***************
*** 8769,8812 **** do_pg_stop_backup(char *labelfile)
  	 */
  	RequestXLogSwitch();
  
- 	XLByteToPrevSeg(stoppoint, _logId, _logSeg);
- 	XLogFileName(stopxlogfilename, ThisTimeLineID, _logId, _logSeg);
- 
- 	/* Use the log timezone here, not the session timezone */
- 	stamp_time = (pg_time_t) time(NULL);
- 	pg_strftime(strfbuf, sizeof(strfbuf),
- 				"%Y-%m-%d %H:%M:%S %Z",
- 				pg_localtime(&stamp_time, log_timezone));
- 
  	/*
! 	 * Write the backup history file
  	 */
! 	XLByteToSeg(startpoint, _logId, _logSeg);
! 	BackupHistoryFilePath(histfilepath, ThisTimeLineID, _logId, _logSeg,
! 						  startpoint.xrecoff % XLogSegSize);
! 	fp = AllocateFile(histfilepath, "w");
! 	if (!fp)
! 		ereport(ERROR,
! 				(errcode_for_file_access(),
! 				 errmsg("could not create file \"%s\": %m",
! 						histfilepath)));
! 	fprintf(fp, "START WAL LOCATION: %X/%X (file %s)\n",
! 			startpoint.xlogid, startpoint.xrecoff, startxlogfilename);
! 	fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n",
! 			stoppoint.xlogid, stoppoint.xrecoff, stopxlogfilename);
! 	/* transfer remaining lines from label to history file */
! 	fprintf(fp, "%s", remaining);
! 	fprintf(fp, "STOP TIME: %s\n", strfbuf);
! 	if (fflush(fp) || ferror(fp) || FreeFile(fp))
! 		ereport(ERROR,
! 				(errcode_for_file_access(),
! 				 errmsg("could not write file \"%s\": %m",
! 						histfilepath)));
  
  	/*
  	 * Clean out any no-longer-needed history files.  As a side effect, this
  	 * will post a .ready file for the newly created history file, notifying
  	 * the archiver that history file may be archived immediately.
  	 */
  	CleanupBackupHistory();
  
--- 8764,8820 ----
  	 */
  	RequestXLogSwitch();
  
  	/*
! 	 * If archiving is enabled, write the backup history file.
  	 */
! 	if (XLogArchivingActive())
! 	{
! 		pg_time_t	stamp_time;
! 		char		strfbuf[128];
! 		char		histfilepath[MAXPGPATH];
! 		char		stopxlogfilename[MAXFNAMELEN];
! 		FILE	   *fp;
! 
! 		XLByteToPrevSeg(stoppoint, _logId, _logSeg);
! 		XLogFileName(stopxlogfilename, ThisTimeLineID, _logId, _logSeg);
! 
! 		/* Use the log timezone here, not the session timezone */
! 		stamp_time = (pg_time_t) time(NULL);
! 		pg_strftime(strfbuf, sizeof(strfbuf),
! 					"%Y-%m-%d %H:%M:%S %Z",
! 					pg_localtime(&stamp_time, log_timezone));
! 
! 		XLByteToSeg(startpoint, _logId, _logSeg);
! 		BackupHistoryFilePath(histfilepath, ThisTimeLineID, _logId, _logSeg,
! 							  startpoint.xrecoff % XLogSegSize);
! 		fp = AllocateFile(histfilepath, "w");
! 		if (!fp)
! 			ereport(ERROR,
! 					(errcode_for_file_access(),
! 					 errmsg("could not create file \"%s\": %m",
! 							histfilepath)));
! 		fprintf(fp, "START WAL LOCATION: %X/%X (file %s)\n",
! 				startpoint.xlogid, startpoint.xrecoff, startxlogfilename);
! 		fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n",
! 				stoppoint.xlogid, stoppoint.xrecoff, stopxlogfilename);
! 		/* transfer remaining lines from label to history file */
! 		fprintf(fp, "%s", remaining);
! 		fprintf(fp, "STOP TIME: %s\n", strfbuf);
! 		if (fflush(fp) || ferror(fp) || FreeFile(fp))
! 			ereport(ERROR,
! 					(errcode_for_file_access(),
! 					 errmsg("could not write file \"%s\": %m",
! 							histfilepath)));
! 	}
  
  	/*
  	 * Clean out any no-longer-needed history files.  As a side effect, this
  	 * will post a .ready file for the newly created history file, notifying
  	 * the archiver that history file may be archived immediately.
+ 	 *
+ 	 * We do this even if archiving is not enabled since there might be the
+ 	 * unnecessary history file which was created when the server was running
+ 	 * before with archiving enabled.
  	 */
  	CleanupBackupHistory();