@@ -8308,6 +8308,21 @@ pg_start_backup(PG_FUNCTION_ARGS)
83088308text * backupid = PG_GETARG_TEXT_P (0 );
83098309bool fast = PG_GETARG_BOOL (1 );
83108310char * backupidstr ;
8311+ XLogRecPtr startpoint ;
8312+ char startxlogstr [MAXFNAMELEN ];
8313+
8314+ backupidstr = text_to_cstring (backupid );
8315+
8316+ startpoint = do_pg_start_backup (backupidstr ,fast );
8317+
8318+ snprintf (startxlogstr ,sizeof (startxlogstr ),"%X/%X" ,
8319+ startpoint .xlogid ,startpoint .xrecoff );
8320+ PG_RETURN_TEXT_P (cstring_to_text (startxlogstr ));
8321+ }
8322+
8323+ XLogRecPtr
8324+ do_pg_start_backup (const char * backupidstr ,bool fast )
8325+ {
83118326XLogRecPtr checkpointloc ;
83128327XLogRecPtr startpoint ;
83138328pg_time_t stamp_time ;
@@ -8335,8 +8350,6 @@ pg_start_backup(PG_FUNCTION_ARGS)
83358350errmsg ("WAL level not sufficient for making an online backup" ),
83368351errhint ("wal_level must be set to \"archive\" or \"hot_standby\" at server start." )));
83378352
8338- backupidstr = text_to_cstring (backupid );
8339-
83408353/*
83418354 * Mark backup active in shared memory. We must do full-page WAL writes
83428355 * during an on-line backup even if not doing so at other times, because
@@ -8459,9 +8472,7 @@ pg_start_backup(PG_FUNCTION_ARGS)
84598472/*
84608473 * We're done. As a convenience, return the starting WAL location.
84618474 */
8462- snprintf (xlogfilename ,sizeof (xlogfilename ),"%X/%X" ,
8463- startpoint .xlogid ,startpoint .xrecoff );
8464- PG_RETURN_TEXT_P (cstring_to_text (xlogfilename ));
8475+ return startpoint ;
84658476}
84668477
84678478/* Error cleanup callback for pg_start_backup */
@@ -8489,6 +8500,19 @@ pg_start_backup_callback(int code, Datum arg)
84898500 */
84908501Datum
84918502pg_stop_backup (PG_FUNCTION_ARGS )
8503+ {
8504+ XLogRecPtr stoppoint ;
8505+ char stopxlogstr [MAXFNAMELEN ];
8506+
8507+ stoppoint = do_pg_stop_backup ();
8508+
8509+ snprintf (stopxlogstr ,sizeof (stopxlogstr ),"%X/%X" ,
8510+ stoppoint .xlogid ,stoppoint .xrecoff );
8511+ PG_RETURN_TEXT_P (cstring_to_text (stopxlogstr ));
8512+ }
8513+
8514+ XLogRecPtr
8515+ do_pg_stop_backup (void )
84928516{
84938517XLogRecPtr startpoint ;
84948518XLogRecPtr stoppoint ;
@@ -8699,9 +8723,35 @@ pg_stop_backup(PG_FUNCTION_ARGS)
86998723/*
87008724 * We're done. As a convenience, return the ending WAL location.
87018725 */
8702- snprintf (stopxlogfilename ,sizeof (stopxlogfilename ),"%X/%X" ,
8703- stoppoint .xlogid ,stoppoint .xrecoff );
8704- PG_RETURN_TEXT_P (cstring_to_text (stopxlogfilename ));
8726+ return stoppoint ;
8727+ }
8728+
8729+
8730+ /*
8731+ * do_pg_abort_backup: abort a running backup
8732+ *
8733+ * This does just the most basic steps of pg_stop_backup(), by taking the
8734+ * system out of backup mode, thus making it a lot more safe to call from
8735+ * an error handler.
8736+ */
8737+ void
8738+ do_pg_abort_backup (void )
8739+ {
8740+ /*
8741+ * OK to clear forcePageWrites
8742+ */
8743+ LWLockAcquire (WALInsertLock ,LW_EXCLUSIVE );
8744+ XLogCtl -> Insert .forcePageWrites = false;
8745+ LWLockRelease (WALInsertLock );
8746+
8747+ /*
8748+ * Remove backup label file
8749+ */
8750+ if (unlink (BACKUP_LABEL_FILE )!= 0 )
8751+ ereport (ERROR ,
8752+ (errcode_for_file_access (),
8753+ errmsg ("could not remove file \"%s\": %m" ,
8754+ BACKUP_LABEL_FILE )));
87058755}
87068756
87078757/*