You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by oy...@apache.org on 2008/03/03 12:40:05 UTC
svn commit: r633043 - in
/db/derby/code/trunk/java/engine/org/apache/derby/impl:
jdbc/EmbedConnection.java services/replication/slave/SlaveController.java
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();