/*
         * Mark that start phase has correctly finished for an exclusive backup.
         * Session-level locks are updated as well to reflect that state.
+        *
+        * Note that CHECK_FOR_INTERRUPTS() must not occur while updating
+        * backup counters and session-level lock. Otherwise they can be
+        * updated inconsistently, and which might cause do_pg_abort_backup()
+        * to fail.
         */
        if (exclusive)
        {
                WALInsertLockAcquireExclusive();
                XLogCtl->Insert.exclusiveBackupState = EXCLUSIVE_BACKUP_IN_PROGRESS;
-               WALInsertLockRelease();
+
+               /* Set session-level lock */
                sessionBackupState = SESSION_BACKUP_EXCLUSIVE;
+               WALInsertLockRelease();
        }
        else
                sessionBackupState = SESSION_BACKUP_NON_EXCLUSIVE;
        }
 
        /*
-        * OK to update backup counters and forcePageWrites
+        * OK to update backup counters, forcePageWrites and session-level lock.
+        *
+        * Note that CHECK_FOR_INTERRUPTS() must not occur while updating them.
+        * Otherwise they can be updated inconsistently, and which might cause
+        * do_pg_abort_backup() to fail.
         */
        WALInsertLockAcquireExclusive();
        if (exclusive)
        {
                XLogCtl->Insert.forcePageWrites = false;
        }
-       WALInsertLockRelease();
 
-       /* Clean up session-level lock */
+       /*
+        * Clean up session-level lock.
+        *
+        * You might think that WALInsertLockRelease() can be called
+        * before cleaning up session-level lock because session-level
+        * lock doesn't need to be protected with WAL insertion lock.
+        * But since CHECK_FOR_INTERRUPTS() can occur in it,
+        * session-level lock must be cleaned up before it.
+        */
        sessionBackupState = SESSION_BACKUP_NONE;
 
+       WALInsertLockRelease();
+
        /*
         * Read and parse the START WAL LOCATION line (this code is pretty crude,
         * but we are not expecting any variability in the file format).
 void
 do_pg_abort_backup(void)
 {
+       /*
+        * Quick exit if session is not keeping around a non-exclusive backup
+        * already started.
+        */
+       if (sessionBackupState == SESSION_BACKUP_NONE)
+               return;
+
        WALInsertLockAcquireExclusive();
        Assert(XLogCtl->Insert.nonExclusiveBackups > 0);
+       Assert(sessionBackupState == SESSION_BACKUP_NON_EXCLUSIVE);
        XLogCtl->Insert.nonExclusiveBackups--;
 
        if (XLogCtl->Insert.exclusiveBackupState == EXCLUSIVE_BACKUP_NONE &&
 
         * Once do_pg_start_backup has been called, ensure that any failure causes
         * us to abort the backup so we don't "leak" a backup counter. For this
         * reason, *all* functionality between do_pg_start_backup() and
-        * do_pg_stop_backup() should be inside the error cleanup block!
+        * the end of do_pg_stop_backup() should be inside the error cleanup block!
         */
 
        PG_ENSURE_ERROR_CLEANUP(base_backup_cleanup, (Datum) 0);
                        else
                                pq_putemptymessage('c');        /* CopyDone */
                }
+
+               endptr = do_pg_stop_backup(labelfile->data, !opt->nowait, &endtli);
        }
        PG_END_ENSURE_ERROR_CLEANUP(base_backup_cleanup, (Datum) 0);
 
-       endptr = do_pg_stop_backup(labelfile->data, !opt->nowait, &endtli);
 
        if (opt->includewal)
        {