OSDN Git Service

If the server is shutting down and we cannot ensure that
authorMasaoFujii <masao.fujii@gmail.com>
Wed, 15 Dec 2010 06:02:36 +0000 (15:02 +0900)
committerMasaoFujii <masao.fujii@gmail.com>
Wed, 15 Dec 2010 06:02:36 +0000 (15:02 +0900)
the transaction has successfully been replicated, we exit
before returning a "success" to the client.

src/backend/replication/walsender.c
src/backend/storage/ipc/procsignal.c
src/backend/tcop/dest.c
src/include/replication/walsender.h
src/include/storage/procsignal.h

index aba5da9..f4e4da5 100644 (file)
@@ -114,7 +114,7 @@ static volatile sig_atomic_t ready_to_stop = false;
 
 /* Flag set by signal handler of backends for replication */
 static volatile sig_atomic_t replication_complete = false;
-static volatile sig_atomic_t replication_abort = false;
+static volatile sig_atomic_t exit_before_complete = false;
 
 /* Signal handlers */
 static void WalSndSigHupHandler(SIGNAL_ARGS);
@@ -1454,14 +1454,8 @@ WaitXLogSend(XLogRecPtr record)
                 * If the primary cannot work any longer, we don't return
                 * a success to the client
                 */
-               if (replication_abort)
-               {
-                       replication_abort = false;
-                       ereport(FATAL,
-                                       (errcode(ERRCODE_ADMIN_SHUTDOWN),
-                                        errmsg("terminating connection due to administrator command "
-                                                       "and replication cancellation")));
-               }
+               if (exit_before_complete)
+                       return;
        }
 }
 
@@ -1535,7 +1529,7 @@ WakeupWalSndWaiters(XLogRecPtr record, bool abort)
 
                if (all_wakeup || XLByteLE(waiter->record, record))
                {
-                       SetProcLatch(waiter->latch, abort ? PROCSIG_REPLICATION_ABORT :
+                       SetProcLatch(waiter->latch, abort ? PROCSIG_EXIT_BEFORE_COMPLETE :
                                                 PROCSIG_REPLICATION_COMPLETE, waiter->backendId);
                        count++;
                }
@@ -1608,10 +1602,20 @@ HandleReplicationComplete(void)
 }
 
 /*
- * This is called when PROCSIG_REPLICATION_ABORT is received.
+ * This is called when PROCSIG_EXIT_BEFORE_COMPLETE is received.
  */
 void
-HandleReplicationAbort(void)
+HandleExitBeforeComplete(void)
+{
+       exit_before_complete = true;
+}
+
+/*
+ * Does the backend have to exit before returning a CommandComplete
+ * message to the client?
+ */
+bool
+NeedExitBeforeComplete(void)
 {
-       replication_abort = true;
+       return exit_before_complete;
 }
index c30a28f..0e6dbd2 100644 (file)
@@ -293,8 +293,8 @@ procsignal_sigusr1_handler(SIGNAL_ARGS)
        if (CheckProcSignal(PROCSIG_REPLICATION_COMPLETE))
                HandleReplicationComplete();
 
-       if (CheckProcSignal(PROCSIG_REPLICATION_ABORT))
-               HandleReplicationAbort();
+       if (CheckProcSignal(PROCSIG_EXIT_BEFORE_COMPLETE))
+               HandleExitBeforeComplete();
 
        latch_sigusr1_handler();
 
index 937e1cf..d2d94e6 100644 (file)
@@ -36,6 +36,7 @@
 #include "executor/tstoreReceiver.h"
 #include "libpq/libpq.h"
 #include "libpq/pqformat.h"
+#include "replication/walsender.h"
 #include "utils/portal.h"
 
 
@@ -144,6 +145,17 @@ EndCommand(const char *commandTag, CommandDest dest)
                case DestRemoteExecute:
 
                        /*
+                        * If the server is shutting down and we cannot ensure that
+                        * the transaction has successfully been replicated, we exit
+                        * before returning a "success" to the client.
+                        */
+                       if (NeedExitBeforeComplete())
+                               ereport(FATAL,
+                                               (errcode(ERRCODE_ADMIN_SHUTDOWN),
+                                                errmsg("terminating connection due to administrator "
+                                                               "command and replication cancellation")));
+
+                       /*
                         * We assume the commandTag is plain ASCII and therefore requires
                         * no encoding conversion.
                         */
index caee109..a601f81 100644 (file)
@@ -89,6 +89,7 @@ extern void WalSndWakeup(void);
 extern void WaitXLogSend(XLogRecPtr record);
 
 extern void HandleReplicationComplete(void);
-extern void HandleReplicationAbort(void);
+extern void HandleExitBeforeComplete(void);
+extern bool NeedExitBeforeComplete(void);
 
 #endif   /* _WALSENDER_H */
index 05158c5..079de79 100644 (file)
@@ -42,7 +42,7 @@ typedef enum
 
        /* Replication interrupts */
        PROCSIG_REPLICATION_COMPLETE,
-       PROCSIG_REPLICATION_ABORT,
+       PROCSIG_EXIT_BEFORE_COMPLETE,
 
        NUM_PROCSIGNALS                         /* Must be last! */
 } ProcSignalReason;