ReplicatedEnvironment (Oracle - Berkeley DB Java Edition API)
Date: 2014-12-16

com.sleepycat.je.rep

## Class ReplicatedEnvironment

- java.lang.Object
- - com.sleepycat.je.Environment
  - - com.sleepycat.je.rep.ReplicatedEnvironment

- All Implemented Interfaces:
    Closeable, AutoCloseable

      public class ReplicatedEnvironment
      extends Environment

  A replicated database environment that is a node in a replication group. Please read the Berkeley DB JE High Availability Overview for an introduction to basic concepts and key terminology.

  Berkeley DB JE High Availability (JE HA) is a replicated, embedded database management system which provides fast, reliable, and scalable data management. JE HA enables replication of an environment across a Replication Group. A ReplicatedEnvironment is a single node in the replication group.

  ReplicatedEnvironment extends `Environment`. All database operations are executed in the same fashion in both replicated and non replicated applications, using `Environment` methods. A ReplicatedEnvironment must be transactional. All replicated databases created in the replicated environment must be transactional as well. However, non-replicated databases may be used as well.

  ReplicatedEnvironment handles are analogous to `Environment` handles. A replicated environment handle is a ReplicatedEnvironment instance; multiple ReplicatedEnvironment instances may be created for the same physical directory. In other words, more than one ReplicatedEnvironment handle may be open at a time for a given environment.

  A ReplicatedEnvironment joins its replication group when it is instantiated. When the constructor returns, the node will have established contact with the other members of the group and will be ready to service operations. The life cycle overview is useful for understanding replication group creation.

  The membership of a replication group is dynamically defined. The group comes into being when ReplicatedEnvironments that are configured as members of a group are created and discover each other. ReplicatedEnvironments are identified by a group name, a node name, and a hostname:port value. Membership information for electable and monitor nodes is stored in an internal, replicated database available to electable and secondary nodes.

  To start a node and join a group, instantiate a ReplicatedEnvironment. The very first instantiation of a node differs slightly from all future instantiations. A brand new, empty node does not yet have access to the membership database, so it must discover the group with the aid of a helper node, which is a fellow member. If this is the very first node of the entire group, there is no available helper. Instead, the helper host address to use is the node's own address. The example below takes the simple approach of creating a replication group by starting up a node that will act as the first master, though it is not necessary to follow this order. Configuring Replicated Environments describes group startup in greater detail.

  To create the master node in a brand new group, instantiate a ReplicatedEnvironment this way:

       EnvironmentConfig envConfig = new EnvironmentConfig();
       envConfig.setAllowCreate(true);
       envConfig.setTransactional(true);

       // Identify the node
       ReplicationConfig repConfig = new ReplicationConfig();
       repConfig.setGroupName("PlanetaryRepGroup");
       repConfig.setNodeName("Mercury");
       repConfig.setNodeHostPort("mercury.acme.com:5001");

       // This is the first node, so its helper is itself
       repConfig.setHelperHosts("mercury.acme.com:5001");

       ReplicatedEnvironment repEnv =
           new ReplicatedEnvironment(envHome, repConfig, envConfig);

  To create a new node when there are other existing group members, set a helper address which points to an existing node in the group. A simple way to bring up a new group is to "chain" the new nodes by having the helpers reference a previously created node.

       EnvironmentConfig envConfig = new EnvironmentConfig();
       envConfig.setAllowCreate(true);
       envConfig.setTransactional(true);

       // Identify the node
       ReplicationConfig repConfig =
           new ReplicationConfig("PlanetaryRepGroup", "Jupiter", "jupiter.acme.com:5002");

       // Use the node at mercury.acme.com:5001 as a helper to find the rest
       // of the group.
       repConfig.setHelperHosts("mercury.acme.com:5001");

       ReplicatedEnvironment repEnv =
           new ReplicatedEnvironment(envHome, repConfig, envConfig);

  In these examples, node Mercury was configured as its own helper, and becomes the first master. The next nodes were configured to use Mercury as their helper, and became replicas. It is also possible to start these in reverse order, bringing mercury up last. In that case, the earlier nodes will block until a helper is awake and can service their requests for group metadata.

  Creating a ReplicatedEnvironment for an existing environment requires less configuration. The call to `EnvironmentConfig.setAllowCreate()` is eliminated to guard against the unintentional creation of a new environment. Also, there is no need to set a helper host address, because the environment exists and has access to the shared, persistent membership information.

       EnvironmentConfig envConfig = new EnvironmentConfig();
       envConfig.setTransactional(true);
       ReplicationConfig repConfig =
           new ReplicationConfig("PlanetaryRepGroup", "Mercury", "mercury.acme.com:5001");

       ReplicatedEnvironment repEnv =
           new ReplicatedEnvironment(envHome, repConfig, envConfig);

  See `ReplicationGroupAdmin` for information on how to remove nodes from the replication group.

  ReplicatedEnvironment properties can be set via the the <environmentHome>/je.properties file, just like `Environment` properties. They follow the same property value precedence rules.

  A replicated environment directory can only be accessed by a read write ReplicatedEnvironment handle or a read only `Environment` handle. In the current release, there is an additional restriction that a read only `Environment` is only permitted when the directory is not also accessed from a different process by a read/write ReplicatedEnvironment. If a read/write ReplicatedEnvironment and a read only `Environment` from two different processes concurrently access an environment directory, there is the small possibility that the read only `Environment` may see see exceptions thrown about an inconsistent log if the ReplicatedEnvironment executes certain kinds of failover. There is no problem if the `Environment` and ReplicatedEnvironment are in the same process, or are not concurrent.

  JE HA prohibits opening a replicated environment directory with a read/write `Environment` handle, because from the group's perspective, unreplicated updates to a single node would cause data inconsistency. To use an existing, non-replicated environment to bootstrap a replication group, use `DbEnableReplication` to do a one time conversion of the directory.

  All other database objects, such as `Database` or `Cursor` (when using the Base API) or `EntityStore` or `PrimaryIndex` (when using the Direct Persistence Layer) should be created, used and closed before calling `close()`.

  Replicated environments can be created with node type `NodeType.ELECTABLE` or `NodeType.SECONDARY`. ELECTABLE nodes can be masters or replicas, and participate in both master elections and commit durability decisions.

  SECONDARY nodes can only be replicas, not masters, and do not participate in either elections or durability decisions. SECONDARY nodes can be used to increase the available number of read replicas without changing the election or durability quorum of the group, and without requiring communication with the secondaries during master elections or transaction commits. As a result, SECONDARY nodes are a good choice for nodes that are connected to the other nodes in the group by high latency network connections, for example over long distance networks. SECONDARY nodes maintain replication streams with the replication group master to update the data contents of their environment.

  You can use SECONDARY nodes to:

  - Provide a copy of the data available at a distant location
  - Maintain an extra copy of the data to increase redundancy
  - Change the number of replicas to adjust to dynamically changing read loads

  Membership information for SECONDARY nodes is not stored persistently, so their membership is only known to the master, and only while the nodes remain connected to the master. Because a SECONDARY node cannot become a master, it will not act as master even if it is the first node created for the group.

  ### Non-replicated Databases in a Replicated Environment

  A database or entity store in a replicated environment is replicated by default, but may be explicitly configured as non-replicated using `DatabaseConfig.setReplicated(boolean)` or `StoreConfig.setReplicated(boolean)`. Such non-replicated databases may be transactional or non-transactional (including deferred-write and temporary). The special considerations for using non-replicated databases in a replicated environment are described below.

  The data in a non-replicated database is not guaranteed to be persistent, for two reasons.

  - When a hard recovery occurs as part of an election, some data at the end of the transaction log may be lost. For a replicated database this data is automatically recovered from other members of the group, but for a non-replicated database it is not.
  - When a node's contents are replaced via network restore or by otherwise copying the transaction log from another node, all previously existing non-replicated databases on that node are destroyed, and the non-replicated databases from the source node are copied along with the replicated data. The non-replicated databases copied from the source node will be in whatever state they were in at the time of the copy.

  Therefore, non-replicated databases are intended to be used primarily for persistent caching and other non-critical local storage. The application is responsible for maintaining the state of the database and handling data loss after one the events described above.

  To perform write operations on a non-replicated database, special considerations are necessary for user-supplied transactions. Namely, the transaction must be configured for `local-write`. A given transaction may be used to write to either replicated databases or non-replicated databases, but not both.

  For auto-commit transactions (when the Transaction parameter is null), the local-write setting is automatically set to correspond to whether the database is replicated. With auto-commit, local-write is always true for a non-replicated database, and always false for a replicated database.

  A local-write transaction automatically uses `Durability.ReplicaAckPolicy.NONE`. A local-write transaction on a Master will thus not be held up, or throw `InsufficientReplicasException`, if the Master is not in contact with a sufficient number of Replicas at the time the transaction is initiated.

  For read operations, a single transaction may be used to read any combination of replicated and non-replicated databases. If only read operations are performed, it is normally desirable to configure a user supplied transaction as `read-only`. Like a local-write transaction, a read-only transaction automatically uses `Durability.ReplicaAckPolicy.NONE`.

  For user-supplied transactions, note that even when accessing only non-replicated databases, group consistency checks are performed by default. In this case it is normally desirable to disable consistency checks by calling `TransactionConfig.setConsistencyPolicy(com.sleepycat.je.ReplicaConsistencyPolicy)` with `NoConsistencyRequiredPolicy.NO_CONSISTENCY`. This allows the non-replicated databases to be accessed regardless of the state of the other members of the group and the network connections to them. When auto-commit is used (when the Transaction parameter is null) with a non-replicated database, consistency checks are automatically disabled.

  Since:
    4.0
  See Also:
    `Environment`, Replication First Steps

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `static class` | `ReplicatedEnvironment.State` The replication node state determines the operations that the application can perform against its replicated environment.

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `ReplicatedEnvironment(File envHome, ReplicationConfig repConfig, EnvironmentConfig envConfig)` A convenience constructor that defaults the replica consistency policy and the initial election policy to be used.
    `ReplicatedEnvironment(File envHome, ReplicationConfig repConfig, EnvironmentConfig envConfig, ReplicaConsistencyPolicy consistencyPolicy, QuorumPolicy initialElectionPolicy)` Creates a replicated environment handle and starts participating in the replication group as either a Master or a Replica.

  - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `void` | `close()` Close this ReplicatedEnvironment and release any resources used by the handle.
    `ReplicationGroup` | `getGroup()` Returns a description of the replication group as known by this node.
    `String` | `getNodeName()` Returns the unique name used to identify this replicated environment.
    `ReplicationConfig` | `getRepConfig()` Return the replication configuration that has been used to create this handle.
    `ReplicationMutableConfig` | `getRepMutableConfig()`
    `ReplicatedEnvironmentStats` | `getRepStats(StatsConfig config)` Returns statistics associated with this environment.
    `ReplicatedEnvironment.State` | `getState()` Returns the current state of the node associated with this replication environment.
    `StateChangeListener` | `getStateChangeListener()` Returns the listener used to receive asynchronous replication node state change events.
    `void` | `printStartupInfo(PrintStream out)` Print a detailed report about the costs of different phases of environment startup.
    `void` | `registerAppStateMonitor(AppStateMonitor appStateMonitor)` Registers an `AppStateMonitor` to receive the application state which this `ReplicatedEnvironment` is running in.
    `void` | `setRepMutableConfig(ReplicationMutableConfig mutableConfig)`
    `void` | `setStateChangeListener(StateChangeListener listener)` Sets the listener used to receive asynchronous replication node state change events.
    `void` | `shutdownGroup(long replicaShutdownTimeout, TimeUnit unit)` Closes this handle and shuts down the Replication Group by forcing all active Replicas to exit.
    `String` | `transferMaster(Set<String> replicas, int timeout, TimeUnit timeUnit)` Transfers the current master state from this node to one of the electable replicas supplied in the argument list.
    `String` | `transferMaster(Set<String> replicas, int timeout, TimeUnit timeUnit, boolean force)` Transfers the current master state from this node to one of the replicas supplied in the argument list.

    - ### Methods inherited from class com.sleepycat.je.Environment

      `beginTransaction, checkpoint, cleanLog, compress, evictMemory, flushLog, getConfig, getDatabaseNames, getHome, getLockStats, getMutableConfig, getStats, getThreadTransaction, getTransactionStats, isInternalHandle, isValid, openDatabase, openSecondaryDatabase, preload, removeDatabase, renameDatabase, setMutableConfig, setThreadTransaction, sync, truncateDatabase, verify`

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Constructor Detail

    - #### ReplicatedEnvironment

          public ReplicatedEnvironment(File envHome,
                               ReplicationConfig repConfig,
                               EnvironmentConfig envConfig,
                               ReplicaConsistencyPolicy consistencyPolicy,
                               QuorumPolicy initialElectionPolicy)
                                throws EnvironmentNotFoundException,
                                       EnvironmentLockedException,
                                       InsufficientLogException,
                                       ReplicaConsistencyException,
                                       IllegalArgumentException

      Creates a replicated environment handle and starts participating in the replication group as either a Master or a Replica. The node's state is determined when it joins the group, and mastership is not preconfigured. If the group has no current master and the node has the default node type of `NodeType.ELECTABLE`, then creation of a handle will trigger an election to determine whether this node will participate as a Master or a Replica.

      If the node participates as a Master, the constructor will return after a sufficient number of Replicas, in accordance with the `initialElectionPolicy` argument, have established contact with the Master.

      If the node participates as a Replica, it will become consistent in accordance with the `consistencyPolicy` argument before returning from the constructor.

      If an election cannot be concluded in the time period defined by `ReplicationConfig.ENV_SETUP_TIMEOUT`, by default it will throw an `UnknownMasterException`. This behavior can be overridden via the `ReplicationConfig.ENV_UNKNOWN_STATE_TIMEOUT` to permit the creation of the handle in the `ReplicatedEnvironment.State.UNKNOWN` state. A handle in UNKNOWN state can be used to service read operations with an appropriately relaxed consistency policy. Note that these timeouts do not apply when opening an environment for the very first time. In the first time case, if the node is not the only group member, or if it is a SECONDARY node, the constructor will wait indefinitely until it can contact an existing group member.

      A brand new node will always join an existing group as a Replica, unless it is the very first electable node that is creating the group. In that case it joins as the Master of the newly formed singleton group. A brand new node must always specify one or more active helper nodes via the `ReplicationMutableConfig.setHelperHosts(String)` method, or via the `<environment home>/je.properties` file. If this is the very first member of a nascent group, it must specify just itself as the helper.

      There are special considerations to keep in mind when a replication group is started and elections are first held to determine a master. The default `QuorumPolicy.SIMPLE_MAJORITY` calls for a simple majority vote. If the group members were previously created and populated, the default election policy may result in the election of a master that may not have the most up to date copy of the environment. This could happen if the best qualified node is slow to start up; it's possible that by the time it's ready to participate in an election, the election has already have completed with a simple majority.

      To avoid this possibility, the method has a parameter initialElectionPolicy, which can be used to specify `QuorumPolicy.ALL`, which will cause the elections to wait until all electable nodes can vote. By ensuring that all the nodes can vote, the best possible node is chosen to be the master at group startup.

      Note that it is the application's responsibility to ensure that all electable nodes coordinate their choice of initialElectionPolicy so that the very first elections held when a group is brought up use the same value for this parameter. This parameter is only used for the first election. After the first election has been held and the group is functioning, subsequent elections do not require participation of all the nodes. A simple majority is sufficient to elect the node with the most up to date environment as the master.

      Parameters:
        `envHome` - The environment's home directory.
        `repConfig` - replication configurations. If null, the default replication configurations are used.
        `envConfig` - environment configurations for this node. If null, the default environment configurations are used.
        `consistencyPolicy` - the consistencyPolicy used by the Replica at startup to make its environment current with respect to the master. This differs from the consistency policy specified `ReplicationConfig.setConsistencyPolicy(com.sleepycat.je.ReplicaConsistencyPolicy)` because it is used only at construction, when the node joins the group for the first time. The consistency policy set in `ReplicationConfig` is used any time a policy is used after node startup, such as at transaction begins.
        `initialElectionPolicy` - the policy to use when holding the initial election.
      Throws:
        `RestartRequiredException` - if some type of corrective action is required. The subclasses of this exception provide further details.
        `ReplicaConsistencyException` - if it is a Replica and cannot satisfy the specified consistency policy within the consistency timeout period
        `UnknownMasterException` - if the `ReplicationConfig.ENV_UNKNOWN_STATE_TIMEOUT` is zero (the default value) and the node cannot join the group in the time period specified by `ReplicationConfig.ENV_SETUP_TIMEOUT`.
        `EnvironmentFailureException` - if an unexpected, internal or environment-wide failure occurs.
        `EnvironmentLockedException` - when an environment cannot be opened for write access because another process has the same environment open for write access. Warning: This exception should be handled when an environment is opened by more than one process.
        `VersionMismatchException` - when the existing log is not compatible with the version of JE that is running. This occurs when a later version of JE was used to create the log. Warning: This exception should be handled when more than one version of JE may be used to access an environment.
        `UnsupportedOperationException` - if the environment exists and has not been enabled for replication.
        `IllegalArgumentException` - if an invalid parameter is specified, for example, an invalid `EnvironmentConfig` parameter.
        `EnvironmentNotFoundException`
        `InsufficientLogException`

    - #### ReplicatedEnvironment

          public ReplicatedEnvironment(File envHome,
                               ReplicationConfig repConfig,
                               EnvironmentConfig envConfig)
                                throws EnvironmentNotFoundException,
                                       EnvironmentLockedException,
                                       ReplicaConsistencyException,
                                       InsufficientLogException,
                                       RollbackException,
                                       IllegalArgumentException

      A convenience constructor that defaults the replica consistency policy and the initial election policy to be used.

      The default replica consistency policy results in the replica being consistent with the master as of the time the handle was created.

      The default initial election policy is `QuorumPolicy.SIMPLE_MAJORITY`

      Throws:
        `RestartRequiredException` - if some type of corrective action is required. The subclasses of this exception provide further details.
        `ReplicaConsistencyException` - if it is a Replica and and cannot be made consistent within the timeout specified by `ReplicationConfig.ENV_CONSISTENCY_TIMEOUT`
        `UnknownMasterException` - if the `ReplicationConfig.ENV_UNKNOWN_STATE_TIMEOUT` has a zero value and the node cannot join the group in the time period specified by the `ReplicationConfig.ENV_SETUP_TIMEOUT` property.
        `EnvironmentLockedException` - when an environment cannot be opened for write access because another process has the same environment open for write access. Warning: This exception should be handled when an environment is opened by more than one process.
        `VersionMismatchException` - when the existing log is not compatible with the version of JE that is running. This occurs when a later version of JE was used to create the log. Warning: This exception should be handled when more than one version of JE may be used to access an environment.
        `EnvironmentFailureException` - if an unexpected, internal or environment-wide failure occurs.
        `UnsupportedOperationException` - if the environment exists and has not been enabled for replication.
        `IllegalArgumentException` - if an invalid parameter is specified, for example, an invalid `EnvironmentConfig` parameter.
        `EnvironmentNotFoundException`
        `InsufficientLogException`
        `RollbackException`
      See Also:
        `ReplicatedEnvironment(File, ReplicationConfig, EnvironmentConfig, ReplicaConsistencyPolicy, QuorumPolicy)`

  - ### Method Detail

    - #### getNodeName

          public String getNodeName()

      Returns the unique name used to identify this replicated environment.
      Returns:
        the node name
      See Also:
        `ReplicationConfig.setNodeName(java.lang.String)`

    - #### getState

          public ReplicatedEnvironment.State getState()
                                               throws DatabaseException

      Returns the current state of the node associated with this replication environment. See `ReplicatedEnvironment.State` for a description of node states.

      If the caller's intent is to track the state of the node, `StateChangeListener` may be a more convenient and efficient approach, rather than using getState() directly.

      Returns:
        the current replication state associated with this node
      Throws:
        `EnvironmentFailureException` - if an unexpected, internal or environment-wide failure occurs.
        `IllegalStateException` - if this handle or the underlying environment has already been closed.
        `DatabaseException`

    - #### getGroup

          public ReplicationGroup getGroup()
                                    throws DatabaseException

      Returns a description of the replication group as known by this node. The replicated group metadata is stored in a replicated database and updates are propagated by the current master node to all replicas. If this node is not the master, it is possible for its description of the group to be out of date, and it will not include information about SECONDARY nodes.
      Returns:
        the group description
      Throws:
        `EnvironmentFailureException` - if an unexpected, internal or environment-wide failure occurs.
        `IllegalStateException` - if this handle or the underlying environment has already been closed.
        `DatabaseException`

    - #### close

          public void close()
                     throws DatabaseException

      Close this ReplicatedEnvironment and release any resources used by the handle.

      When the last handle is closed, allocated resources are freed, and daemon threads are stopped, even if they are performing work. The node ceases participation in the replication group. If the node was currently the master, the rest of the group will hold an election. If a quorum of nodes can participate in the election, a new master will be chosen.

      The ReplicatedEnvironment should not be closed while any other type of handle that refers to it is not yet closed. For example, the ReplicatedEnvironment should not be closed while there are open Database instances, or while transactions in the environment have not yet committed or aborted. Specifically, this includes `Database`, `Cursor` and `Transaction` handles.

      WARNING: To guard against memory leaks, the application should discard all references to the closed handle. While BDB makes an effort to discard references from closed objects to the allocated memory for an environment, this behavior is not guaranteed. The safe course of action for an application is to discard all references to closed BDB objects.

      Specified by:
        `close` in interface `Closeable`
      Specified by:
        `close` in interface `AutoCloseable`
      Overrides:
        `close` in class `Environment`
      Throws:
        `DatabaseException`

    - #### setStateChangeListener

          public void setStateChangeListener(StateChangeListener listener)
                                      throws DatabaseException

      Sets the listener used to receive asynchronous replication node state change events. Note that there is one listener per replication node, not one per handle. Invoking this method replaces the previous Listener. Invoking this method typically results in an immediate callback to the application via the `StateChangeListener.stateChange(com.sleepycat.je.rep.StateChangeEvent)` method, so that the application is made aware of the existing state of the node at the time `StateChangeListener` is first established.
      Parameters:
        `listener` - the state change listener.
      Throws:
        `EnvironmentFailureException` - if an unexpected, internal or environment-wide failure occurs.
        `IllegalStateException` - if this handle or the underlying environment has already been closed.
        `DatabaseException`

    - #### getStateChangeListener

          public StateChangeListener getStateChangeListener()
                                                     throws DatabaseException

      Returns the listener used to receive asynchronous replication node state change events. A StateChangeListener provides the replication application with an asynchronous mechanism for tracking the `State` of the replicated environment.

      Note that there is one listener per replication node, not one per ReplicatedEnvironment handle.

      Throws:
        `EnvironmentFailureException` - if an unexpected, internal or environment-wide failure occurs.
        `IllegalStateException` - if this handle or the underlying environment has already been closed.
        `DatabaseException`

    - #### setRepMutableConfig

          public void setRepMutableConfig(ReplicationMutableConfig mutableConfig)
                                   throws DatabaseException

      Throws:
        `EnvironmentFailureException` - if an unexpected, internal or environment-wide failure occurs.
        `IllegalStateException` - if this handle or the underlying environment has already been closed.
        `DatabaseException`

    - #### getRepMutableConfig

          public ReplicationMutableConfig getRepMutableConfig()
                                                       throws DatabaseException

      Throws:
        `EnvironmentFailureException` - if an unexpected, internal or environment-wide failure occurs.
        `IllegalStateException` - if this handle or the underlying environment has already been closed.
        `DatabaseException`

    - #### getRepConfig

          public ReplicationConfig getRepConfig()
                                         throws DatabaseException

      Return the replication configuration that has been used to create this handle. This is derived from the original configuration argument, after cloning a copy to keep it distinct from the user's instance, applying je.properties settings, and validating against the underlying node.
      Returns:
        this handle's configuration.
      Throws:
        `EnvironmentFailureException` - if an unexpected, internal or environment-wide failure occurs.
        `IllegalStateException` - if this handle or the underlying environment has already been closed.
        `DatabaseException`

    - #### getRepStats

          public ReplicatedEnvironmentStats getRepStats(StatsConfig config)
                                                 throws DatabaseException

      Returns statistics associated with this environment. See `ReplicatedEnvironmentStats` for the kind of information available.
      Parameters:
        `config` - is used to specify attributes such as whether the stats should be cleared, whether the complete set of stats should be obtained, etc.
      Throws:
        `EnvironmentFailureException` - if an unexpected, internal or environment-wide failure occurs.
        `IllegalStateException` - if this handle or the underlying environment has already been closed.
        `DatabaseException`

    - #### printStartupInfo

          public void printStartupInfo(PrintStream out)

      Print a detailed report about the costs of different phases of environment startup. This report is by default logged to the je.info file if startup takes longer than je.env.startupThreshold.
      Overrides:
        `printStartupInfo` in class `Environment`

    - #### shutdownGroup

          public void shutdownGroup(long replicaShutdownTimeout,
                           TimeUnit unit)
                             throws IllegalStateException

      Closes this handle and shuts down the Replication Group by forcing all active Replicas to exit.

      This method must be invoked on the node that's currently the Master after all other outstanding handles have been closed.

      The Master waits for all active Replicas to catch up so that they have a current set of logs, and then shuts them down. The Master will wait for a maximum of `replicaShutdownTimeout` for a Replica to catch up. If the Replica has not caught up in this time period it will force the Replica to shut down before it is completely caught up. A negative or zero `replicaShutdownTimeout` value will result in an immediate shutdown without waiting for lagging Replicas to catch up. Nodes that are currently inactive cannot be contacted by the Master, as a consequence, their state is not impacted by the shutdown.

      The shutdown operation will close this handle on the Master node. The environments on Replica nodes will be invalidated, and attempts to use those handles will result in a `GroupShutdownException` being thrown. The application is responsible for closing the remaining handles on the Replica.

      Parameters:
        `replicaShutdownTimeout` - the maximum amount of time the Master waits for a Replica to shutdown.
        `unit` - the time unit associated with the `replicaShutdownTimeout`
      Throws:
        `IllegalStateException` - if the method is invoked on a node that's not currently the Master, or there are other open handles to this Environment.

    - #### registerAppStateMonitor

          public void registerAppStateMonitor(AppStateMonitor appStateMonitor)
                                       throws IllegalStateException

      Registers an `AppStateMonitor` to receive the application state which this `ReplicatedEnvironment` is running in. Note that there is only one `AppStateMonitor` per replication node, not one per handle. Invoking this method replaces the previous `AppStateMonitor`.

      After registration, the application state can be returned by invoking `ReplicationGroupAdmin.getNodeState(com.sleepycat.je.rep.ReplicationNode, int)`.

      Parameters:
        `appStateMonitor` - the user implemented AppStateMonitor
      Throws:
        `IllegalStateException` - if this handle or the underlying environment has already been closed.

    - #### transferMaster

          public String transferMaster(Set<String> replicas,
                              int timeout,
                              TimeUnit timeUnit)

      Transfers the current master state from this node to one of the electable replicas supplied in the argument list. The replica that is actually chosen to be the new master is the one with which the Master Transfer can be completed most rapidly. The transfer operation ensures that all changes at this node are available at the new master upon conclusion of the operation.

      The following sequence of steps is used to accomplish the transfer:

      1. The master first waits for at least one replica, from amongst the supplied `Set` of candidate replicas, to become reasonably current. It may have to wait for at least one of the replicas to establish a feeder, if none of them are currently connected to the master. "Reasonably current" means that the replica is close enough to the end of the transaction stream that it has managed to acknowledge a transaction within the time that the commit thread is still awaiting acknowledgments. If the candidate replicas are working through a long backlog after having been disconnected, this can take some time, so the timeout value should be chosen to allow for this possibility.
      2. The master blocks new transactions from being committed or aborted.
      3. The master now waits for one of the candidate replicas to become fully current (completely caught up with the end of the log on the master). The first replica that becomes current is the one that is chosen to become the new master. This second wait period is expected to be brief, since it only has to wait until transactions that were committed in the interval between step 1) and step 2) have been acknowledged by a replica.
      4. The master sends messages to all other nodes announcing the chosen replica as the new master. This node will eventually become a replica, and any subsequent attempt commit or abort existing transactions, or to do write operations will result in a `ReplicaWriteException`.
      5. The current master releases the transactions that were blocked in step 2) allowing them to proceed. The released transactions will fail with `ReplicaWriteException` since the environment has become a replica.
      Parameters:
        `replicas` - the set of replicas to be considered when choosing the new master. The method returns immediately if this node is a member of the set.
        `timeout` - the amount of time to allow for the transfer to be accomplished. A `MasterTransferFailureException` is thrown if the transfer is not accomplished within this timeout period.
        `timeUnit` - the time unit associated with the timeout
      Returns:
        the name of the replica that was chosen to be the new master from amongst the set of supplied replicas
      Throws:
        `MasterTransferFailureException` - if the master transfer operation fails
        `IllegalArgumentException` - if any of the named replicas is not a member of the replication group or is not of type `NodeType.ELECTABLE`
        `IllegalStateException` - if this node is not currently the master

    - #### transferMaster

          public String transferMaster(Set<String> replicas,
                              int timeout,
                              TimeUnit timeUnit,
                              boolean force)

      Transfers the current master state from this node to one of the replicas supplied in the argument list.
      Parameters:
        `force` - true if this request should supersede and cancel any currently pending Master Transfer operation
      See Also:
        `transferMaster(Set, int, TimeUnit)`

Copyright (c) 2004, 2014 Oracle and/or its affiliates. All rights reserved.