OSDN Git Service

Split pg_start_backup() and pg_stop_backup() into two pieces
authorMagnus Hagander <magnus@hagander.net>
Sun, 9 Jan 2011 20:00:28 +0000 (21:00 +0100)
committerMagnus Hagander <magnus@hagander.net>
Sun, 9 Jan 2011 20:00:28 +0000 (21:00 +0100)
Move the actual functionality into a separate function that's
easier to call internally, and change the SQL-callable function
to be a wrapper calling this.

Also create a pg_abort_backup() function, only callable internally,
that does only the most vital parts of pg_stop_backup(), making it
safe(r) to call from error handlers.

src/backend/access/transam/xlog.c
src/include/access/xlog.h

index 818a59f..5b6a230 100644 (file)
@@ -8308,6 +8308,21 @@ pg_start_backup(PG_FUNCTION_ARGS)
        text       *backupid = PG_GETARG_TEXT_P(0);
        bool            fast = PG_GETARG_BOOL(1);
        char       *backupidstr;
+       XLogRecPtr  startpoint;
+       char            startxlogstr[MAXFNAMELEN];
+
+       backupidstr = text_to_cstring(backupid);
+
+       startpoint = do_pg_start_backup(backupidstr, fast);
+
+       snprintf(startxlogstr, sizeof(startxlogstr), "%X/%X",
+                        startpoint.xlogid, startpoint.xrecoff);
+       PG_RETURN_TEXT_P(cstring_to_text(startxlogstr));
+}
+
+XLogRecPtr
+do_pg_start_backup(const char *backupidstr, bool fast)
+{
        XLogRecPtr      checkpointloc;
        XLogRecPtr      startpoint;
        pg_time_t       stamp_time;
@@ -8335,8 +8350,6 @@ pg_start_backup(PG_FUNCTION_ARGS)
                          errmsg("WAL level not sufficient for making an online backup"),
                                 errhint("wal_level must be set to \"archive\" or \"hot_standby\" at server start.")));
 
-       backupidstr = text_to_cstring(backupid);
-
        /*
         * Mark backup active in shared memory.  We must do full-page WAL writes
         * during an on-line backup even if not doing so at other times, because
@@ -8459,9 +8472,7 @@ pg_start_backup(PG_FUNCTION_ARGS)
        /*
         * We're done.  As a convenience, return the starting WAL location.
         */
-       snprintf(xlogfilename, sizeof(xlogfilename), "%X/%X",
-                        startpoint.xlogid, startpoint.xrecoff);
-       PG_RETURN_TEXT_P(cstring_to_text(xlogfilename));
+       return startpoint;
 }
 
 /* Error cleanup callback for pg_start_backup */
@@ -8490,6 +8501,19 @@ pg_start_backup_callback(int code, Datum arg)
 Datum
 pg_stop_backup(PG_FUNCTION_ARGS)
 {
+       XLogRecPtr      stoppoint;
+       char            stopxlogstr[MAXFNAMELEN];
+
+       stoppoint = do_pg_stop_backup();
+
+       snprintf(stopxlogstr, sizeof(stopxlogstr), "%X/%X",
+                        stoppoint.xlogid, stoppoint.xrecoff);
+       PG_RETURN_TEXT_P(cstring_to_text(stopxlogstr));
+}
+
+XLogRecPtr
+do_pg_stop_backup(void)
+{
        XLogRecPtr      startpoint;
        XLogRecPtr      stoppoint;
        XLogRecData rdata;
@@ -8699,9 +8723,35 @@ pg_stop_backup(PG_FUNCTION_ARGS)
        /*
         * We're done.  As a convenience, return the ending WAL location.
         */
-       snprintf(stopxlogfilename, sizeof(stopxlogfilename), "%X/%X",
-                        stoppoint.xlogid, stoppoint.xrecoff);
-       PG_RETURN_TEXT_P(cstring_to_text(stopxlogfilename));
+       return stoppoint;
+}
+
+
+/*
+ * do_pg_abort_backup: abort a running backup
+ *
+ * This does just the most basic steps of pg_stop_backup(), by taking the
+ * system out of backup mode, thus making it a lot more safe to call from
+ * an error handler.
+ */
+void
+do_pg_abort_backup(void)
+{
+       /*
+        * OK to clear forcePageWrites
+        */
+       LWLockAcquire(WALInsertLock, LW_EXCLUSIVE);
+       XLogCtl->Insert.forcePageWrites = false;
+       LWLockRelease(WALInsertLock);
+
+       /*
+        * Remove backup label file
+        */
+       if (unlink(BACKUP_LABEL_FILE) != 0)
+               ereport(ERROR,
+                               (errcode_for_file_access(),
+                                errmsg("could not remove file \"%s\": %m",
+                                               BACKUP_LABEL_FILE)));
 }
 
 /*
index 2ed1c64..74d3427 100644 (file)
@@ -312,4 +312,8 @@ extern void HandleStartupProcInterrupts(void);
 extern void StartupProcessMain(void);
 extern void WakeupRecovery(void);
 
+extern XLogRecPtr do_pg_start_backup(const char *backupidstr, bool fast);
+extern XLogRecPtr do_pg_stop_backup(void);
+extern void do_pg_abort_backup(void);
+
 #endif   /* XLOG_H */