db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From oyste...@apache.org
Subject svn commit: r633043 - in /db/derby/code/trunk/java/engine/org/apache/derby/impl: jdbc/EmbedConnection.java services/replication/slave/SlaveController.java
Date Mon, 03 Mar 2008 11:40:05 GMT
Author: oysteing
Date: Mon Mar  3 03:40:04 2008
New Revision: 633043

URL: http://svn.apache.org/viewvc?rev=633043&view=rev
Log:
DERBY-3205: Slave failover follow-up
Contributed by Jorgen Loland.
M java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java
 - ensures that no other operation is used in the same conn
   attempt as failover (also added this check for all other
   repliation operations)
 - checks that the caller of master-side failover is db
   owner (also added to other master-side replication commands)
M java/engine/org/apache/derby/impl/services/replication/slave/SlaveController.java
 - replication network connection is shutdown (including streams
   and socket) when failover is processed

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/slave/SlaveController.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java?rev=633043&r1=633042&r2=633043&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java Mon Mar
 3 03:40:04 2008
@@ -236,6 +236,22 @@
 
             boolean isFailoverMasterBoot = false;
             boolean isFailoverSlaveBoot = false;
+
+            // check that a replication operation is not combined with
+            // other operations
+            String replicationOp = getReplicationOperation(info);
+            if (replicationOp!= null) {
+                if (createBoot ||
+                    shutdown ||
+                    isTwoPhaseEncryptionBoot ||
+                    isTwoPhaseUpgradeBoot) {
+                    throw StandardException.
+                        newException(SQLState.
+                                     REPLICATION_CONFLICTING_ATTRIBUTES,
+                                     replicationOp);
+                }
+            }
+
             if (isReplicationFailover(info)) {
                 // Check that the database has been booted - otherwise throw 
                 // exception.
@@ -262,13 +278,6 @@
                     throw StandardException.newException(
                         SQLState.CANNOT_START_SLAVE_ALREADY_BOOTED,
                         getTR().getDBName());
-                } else if (createBoot ||
-                           shutdown ||
-                           isTwoPhaseEncryptionBoot ||
-                           isTwoPhaseUpgradeBoot) {
-                    throw StandardException.newException(
-                        SQLState.REPLICATION_CONFLICTING_ATTRIBUTES,
-                        Attribute.REPLICATION_START_SLAVE);
                 }
 
                 // We need to boot the slave database two times. The
@@ -283,10 +292,10 @@
                                  SlaveFactory.SLAVE_PRE_MODE);
             }
 
-            // DERBY-3383: stopSlave must be performed before
-            // bootDatabase so that we don't accidentally boot the db
-            // if stopSlave is requested on an unbooted db
             if (isStopReplicationSlaveBoot(info)) {
+                // DERBY-3383: stopSlave must be performed before
+                // bootDatabase so that we don't accidentally boot the db
+                // if stopSlave is requested on an unbooted db.
                 // An exception is always thrown from this method. If
                 // stopSlave is requested, we never get past this point
                 handleStopReplicationSlave(database, info);
@@ -294,11 +303,15 @@
                 internalStopReplicationSlave(database, info);
                 return;
             } else if (isFailoverSlaveBoot) {
-                // failover on slave must be done before tr.startTransaction
-                // because startTrans will try to establish a connection to 
-                // the database through Database.setupConnection, which throws
-                // an exception in slave mode.
+                // For slave side failover, we perform failover before 
+                // connecting to the db (tr.startTransaction further down sets
+                // up the connection). If a connection had been
+                // established first, the connection attempt would throw an 
+                // exception saying that a database in slave mode cannot be 
+                // connected to
                 handleFailoverSlave(database);
+                // db is no longer in slave mode - proceed with normal 
+                // connection attempt
             }
 
 			if (database != null)
@@ -366,18 +379,26 @@
 			// the rest.
 			tr.startTransaction();
 
-			if (isStartReplicationMasterBoot(info) && !shutdown) {
-				handleStartReplicationMaster(tr, info);
-			} else if (isStopReplicationMasterBoot(info)) {
-				// Stopping replication master can be done
-				// simultaneously with a database shutdown operation
-				handleStopReplicationMaster(tr, info);
-			} else if (isFailoverMasterBoot) {
-				// failover on master must be done after tr.startTransaction
-				// because that will establish a connection with the database,
-				// which in turn is used to check authentication/authorization
-				handleFailoverMaster(tr);
-			}
+            if (isStartReplicationMasterBoot(info) ||
+                isStopReplicationMasterBoot(info) ||
+                isFailoverMasterBoot) {
+
+                if (!usingNoneAuth &&
+                    getLanguageConnection().usesSqlAuthorization()) {
+                    // a failure here leaves database booted, but no
+                    // operation has taken place and the connection is
+                    // rejected.
+                    checkIsDBOwner(OP_REPLICATION);
+                }
+
+                if (isStartReplicationMasterBoot(info)) {
+                    handleStartReplicationMaster(tr, info);
+                } else if (isStopReplicationMasterBoot(info)) {
+                    handleStopReplicationMaster(tr, info);
+                } else if (isFailoverMasterBoot) {
+                    handleFailoverMaster(tr);
+                }
+            }
 
 			if (isTwoPhaseEncryptionBoot ||
 				isTwoPhaseUpgradeBoot ||
@@ -686,6 +707,44 @@
         return Boolean.valueOf(
                p.getProperty(Attribute.REPLICATION_INTERNAL_SHUTDOWN_SLAVE)).
                booleanValue();
+    }
+
+    private String getReplicationOperation(Properties p) 
+        throws StandardException {
+
+        String operation = null;
+        int opcount = 0;
+        if (isStartReplicationSlaveBoot(p)) {
+            operation = Attribute.REPLICATION_START_SLAVE;
+            opcount++;
+        } 
+        if (isStartReplicationMasterBoot(p)) {
+            operation = Attribute.REPLICATION_START_MASTER;
+            opcount++;
+        }
+        if (isStopReplicationSlaveBoot(p)) {
+            operation = Attribute.REPLICATION_STOP_SLAVE;
+            opcount++;
+        }
+        if (isInternalShutdownSlaveDatabase(p)) {
+            operation = Attribute.REPLICATION_INTERNAL_SHUTDOWN_SLAVE;
+            opcount++;
+        }
+        if (isStopReplicationMasterBoot(p)) {
+            operation = Attribute.REPLICATION_STOP_MASTER;
+            opcount++;
+        } 
+        if (isReplicationFailover(p)) {
+            operation = Attribute.REPLICATION_FAILOVER;
+            opcount++;
+        }
+
+        if (opcount > 1) {
+            throw StandardException.
+                newException(SQLState.REPLICATION_CONFLICTING_ATTRIBUTES,
+                             operation);
+        }
+        return operation;
     }
 
     private void handleStartReplicationMaster(TransactionResourceImpl tr,

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/slave/SlaveController.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/slave/SlaveController.java?rev=633043&r1=633042&r2=633043&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/slave/SlaveController.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/replication/slave/SlaveController.java
Mon Mar  3 03:40:04 2008
@@ -248,24 +248,7 @@
      */
     private void stopSlave() throws StandardException {
         inReplicationSlaveMode = false;
-
-        try {
-            if (logReceiverThread != null) {
-                logReceiverThread.interrupt();
-            }
-        } catch (SecurityException se) {
-            // Do nothing - the logReceiverThread will get an
-            // exception when receiver.tearDown is called below
-        }
-
-        try {
-            // Unplug the replication network connection layer
-            if (receiver != null) {
-                receiver.tearDown(); 
-            }
-        } catch (IOException ioe) {
-            ReplicationLogger.logError(null, ioe, dbname);
-        }
+        teardownNetwork();
 
         logToFile.stopReplicationSlaveRole();
 
@@ -290,6 +273,7 @@
                 SQLState.SLAVE_OPERATION_DENIED_WHILE_CONNECTED);
         }
         doFailover();
+        teardownNetwork();
     } 
 
     /**
@@ -456,6 +440,17 @@
         }
     }
 
+    private void teardownNetwork() {
+        try {
+            // Unplug the replication network connection layer
+            if (receiver != null) {
+                receiver.tearDown();
+                receiver = null;
+            }
+        } catch (IOException ioe) {
+            ReplicationLogger.logError(null, ioe, dbname);
+        }
+    }
 
     ///////////////////////////////////////////////////////////////////////////
     // Inner Class - Thread used to apply chunks of log received from master //
@@ -482,6 +477,7 @@
                         ReplicationMessage ack = new ReplicationMessage
                             (ReplicationMessage.TYPE_ACK, "failover succeeded");
                         receiver.sendMessage(ack);
+                        teardownNetwork();
                         break;
                     case ReplicationMessage.TYPE_STOP:
                         stopSlave();



Mime
View raw message