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/01/18 09:22:07 UTC
svn commit: r613097 - in /db/derby/code/trunk/java:
engine/org/apache/derby/iapi/reference/ engine/org/apache/derby/impl/jdbc/
engine/org/apache/derby/loc/ shared/org/apache/derby/shared/common/reference/
Author: oysteing
Date: Fri Jan 18 00:22:06 2008
New Revision: 613097
URL: http://svn.apache.org/viewvc?rev=613097&view=rev
Log:
DERBY-3205: Implement connection url attribute for starting slave.
(Contributed by Jorgen Loland)
Modified:
db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Attribute.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java
db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/Attribute.java
db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Attribute.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Attribute.java?rev=613097&r1=613096&r2=613097&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Attribute.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Attribute.java Fri Jan 18 00:22:06 2008
@@ -113,6 +113,16 @@
String REPLICATION_STOP_MASTER = "stopMaster";
/**
+ * Attribute name to start replication slave mode for a database.
+ */
+ String REPLICATION_START_SLAVE = "startSlave";
+
+ /**
+ * Attribute name to stop replication slave mode for a database.
+ */
+ String REPLICATION_STOP_SLAVE = "stopSlave";
+
+ /**
* If startMaster is true, this attribute is used to specify the
* host name the master should connect to. This is a required
* attribute.
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=613097&r1=613096&r2=613097&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 Fri Jan 18 00:22:06 2008
@@ -48,6 +48,9 @@
import org.apache.derby.iapi.sql.dictionary.DataDictionary;
import org.apache.derby.iapi.store.access.XATransactionController;
+import org.apache.derby.iapi.services.replication.master.MasterFactory;
+import org.apache.derby.iapi.services.replication.slave.SlaveFactory;
+
/* can't import due to name overlap:
import java.sql.Connection;
import java.sql.ResultSet;
@@ -229,11 +232,38 @@
isEncryptionBoot(info));
boolean isTwoPhaseUpgradeBoot = (!createBoot &&
isHardUpgradeBoot(info));
+ boolean isStartSlaveBoot = isStartReplicationSlaveBoot(info);
// Save original properties if we modified them for
// two phase encryption or upgrade boot.
Properties savedInfo = null;
+ if (isStartSlaveBoot) {
+ if (database != null) {
+ 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
+ // first boot will check authentication and
+ // authorization. The second boot will put the
+ // database in replication slave mode. SLAVE_PRE_MODE
+ // ensures that log records are not written to disk
+ // during the first boot. This is necessary because
+ // the second boot needs a log that is exactly equal
+ // to the log at the master.
+ info.setProperty(SlaveFactory.REPLICATION_MODE,
+ SlaveFactory.SLAVE_PRE_MODE);
+ }
+
if (database != null)
{
// database already booted by someone else
@@ -312,23 +342,56 @@
handleStopReplicationMaster(tr, info);
}
- if (isTwoPhaseEncryptionBoot || isTwoPhaseUpgradeBoot) {
-
- // DERBY-2264: shutdown and boot again with encryption or
- // upgrade attributes active. This is restricted to the
- // database owner if authentication and sqlAuthorization is on.
+ if (isTwoPhaseEncryptionBoot ||
+ isTwoPhaseUpgradeBoot ||
+ isStartSlaveBoot) {
+
+ // shutdown and boot again with encryption, upgrade or
+ // start replication slave attributes active. This is
+ // restricted to the database owner if authentication
+ // and sqlAuthorization is on.
if (!usingNoneAuth &&
getLanguageConnection().usesSqlAuthorization()) {
- // a failure here leaves database booted, but no
- // (re)encryption has taken place and the connection is
- // rejected.
- checkIsDBOwner(isTwoPhaseEncryptionBoot? OP_ENCRYPT :
- OP_HARD_UPGRADE);
+ int operation;
+ if (isTwoPhaseEncryptionBoot) {
+ operation = OP_ENCRYPT;
+ } else if (isTwoPhaseUpgradeBoot) {
+ operation = OP_HARD_UPGRADE;
+ } else {
+ operation = OP_REPLICATION;
+ }
+ try {
+ // a failure here leaves database booted, but no
+ // (re)encryption has taken place and the connection is
+ // rejected.
+ checkIsDBOwner(operation);
+ } catch (SQLException sqle) {
+ if (isStartSlaveBoot) {
+ // If authorization fails for the start
+ // slave command, we want to shutdown the
+ // database which is currently in the
+ // SLAVE_PRE_MODE.
+ handleException(tr.shutdownDatabaseException());
+ }
+ throw sqle;
+ }
+ }
+
+ if (isStartSlaveBoot) {
+ // Let the next boot of the database be
+ // replication slave mode
+ info.setProperty(SlaveFactory.REPLICATION_MODE,
+ SlaveFactory.SLAVE_MODE);
+ info.setProperty(SlaveFactory.SLAVE_DB,
+ getTR().getDBName());
+ } else {
+ // reboot using saved properties which
+ // include the (re)encyption or upgrade attribute(s)
+ info = savedInfo;
}
- // shutdown and reboot using saved properties which
- // include the (re)encyption or upgrade attribute(s)
- info = savedInfo;
+ // Authentication and authorization done - shutdown
+ // the database
handleException(tr.shutdownDatabaseException());
restoreContextStack();
tr = new TransactionResourceImpl(driver, url, info);
@@ -336,6 +399,8 @@
setupContextStack();
context = pushConnectionContext(tr.getContextManager());
+ // Reboot the database in the correct
+ // encrypt/upgrade/slave replication mode
if (!bootDatabase(info, false))
{
if (SanityManager.DEBUG) {
@@ -347,9 +412,20 @@
setInactive();
return;
}
- // don't need to check user credentials again, did
- // that on first plain boot, so just start
- tr.startTransaction();
+
+ if (isStartSlaveBoot) {
+ // We don't return a connection to the client who
+ // called startSlave. Rather, we throw an
+ // exception stating that replication slave mode
+ // has been successfully started for the database
+ throw StandardException.newException(
+ SQLState.REPLICATION_SLAVE_STARTED_OK,
+ getTR().getDBName());
+ } else {
+ // don't need to check user credentials again, did
+ // that on first plain boot, so just start
+ tr.startTransaction();
+ }
}
// now we have the database connection, we can shut down
@@ -482,6 +558,12 @@
p.getProperty(Attribute.UPGRADE_ATTR)).booleanValue();
}
+ private boolean isStartReplicationSlaveBoot(Properties p) {
+ return ((Boolean.valueOf(
+ p.getProperty(Attribute.REPLICATION_START_SLAVE)).
+ booleanValue()));
+ }
+
private boolean isStartReplicationMasterBoot(Properties p) {
return ((Boolean.valueOf(
p.getProperty(Attribute.REPLICATION_START_MASTER)).
@@ -533,9 +615,7 @@
tr.getDatabase().startReplicationMaster(slavehost,
slaveport,
- org.apache.derby.iapi.
- services.replication.
- master.MasterFactory.
+ MasterFactory.
ASYNCHRONOUS_MODE);
}
Modified: db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml?rev=613097&r1=613096&r2=613097&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml Fri Jan 18 00:22:06 2008
@@ -4763,6 +4763,23 @@
<text>Could not stop replication because the database is not in replication master mode.</text>
</msg>
+ <msg>
+ <name>XRE08</name>
+ <text>Replication slave mode started successfully for database '{0}'. Connection refused because the database is in replication slave mode. </text>
+ <arg>dbname</arg>
+ </msg>
+
+ <msg>
+ <name>XRE09</name>
+ <text>Cannot start replication slave mode for database '{0}'. The database has already been booted. </text>
+ <arg>dbname</arg>
+ </msg>
+
+ <msg>
+ <name>XRE10</name>
+ <text>Conflicting attributes specified. See reference manual for attributes allowed in combination with replication attribute '{0}'.</text>
+ <arg>attribute</arg>
+ </msg>
</family>
Modified: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/Attribute.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/Attribute.java?rev=613097&r1=613096&r2=613097&view=diff
==============================================================================
--- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/Attribute.java (original)
+++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/Attribute.java Fri Jan 18 00:22:06 2008
@@ -103,6 +103,16 @@
String REPLICATION_STOP_MASTER = "stopMaster";
/**
+ * Attribute name to start replication slave mode for a database.
+ */
+ String REPLICATION_START_SLAVE = "startSlave";
+
+ /**
+ * Attribute name to stop replication slave mode for a database.
+ */
+ String REPLICATION_STOP_SLAVE = "stopSlave";
+
+ /**
* If startMaster is true, this attribute is used to specify the
* host name the master should connect to. This is a required
* attribute.
Modified: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java?rev=613097&r1=613096&r2=613097&view=diff
==============================================================================
--- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java (original)
+++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java Fri Jan 18 00:22:06 2008
@@ -1765,5 +1765,8 @@
String REPLICATION_LOG_OUT_OF_SYNCH = "XRE05";
String REPLICATION_MASTER_TIMED_OUT = "XRE06";
String REPLICATION_UNABLE_TO_STOP_MASTER = "XRE07";
+ String REPLICATION_SLAVE_STARTED_OK = "XRE08";
+ String CANNOT_START_SLAVE_ALREADY_BOOTED = "XRE09";
+ String REPLICATION_CONFLICTING_ATTRIBUTES = "XRE10";
}