Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*-
   * See the file LICENSE for redistribution information.
   *
   * Copyright (c) 2002, 2013 Oracle and/or its affiliates.  All rights reserved.
   *
   */
  
  package com.sleepycat.je.rep;
  
 import java.io.File;
 import java.util.List;
 import java.util.Set;
 
Obtains log files for a Replica from other members of the replication group. A Replica may need to do so if it has been offline for some time, and has fallen behind in its execution of the replication stream.

During that time, the connected nodes may have reduced their log files by doing log cleaning. When this node rejoins the group, it is possible that the current Master's log files do not go back far enough to adequately href="{@docRoot/../ReplicationGuide/lifecycle.html#lifecycle-nodestartup">sync up} this node. In that case, the node can use a NetworkRestore object to copy the log files from one of the nodes in the group.

A Replica discovers the need for a NetworkRestore operation when a call to ReplicatedEnvironment() fails with a InsufficientLogException.

A call to NetworkRestore.execute() will copy the required log files from a member of the group who owns the files and seems to be the least busy. For example:

  try {
     node = new ReplicatedEnvironment(envDir, envConfig, repConfig);
 } catch (InsufficientLogException insufficientLogEx) {

     NetworkRestore restore = new NetworkRestore();
     NetworkRestoreConfig config = new NetworkRestoreConfig();
     config.setRetainLogFiles(false); // delete obsolete log files.

     // Use the members returned by insufficientLogEx.getLogProviders() to
     // select the desired subset of members and pass the resulting list
     // as the argument to config.setLogProviders(), if the default selection
     // of providers is not suitable.

     restore.execute(insufficientLogEx, config);

     // retry
     node = new ReplicatedEnvironment(envDir, envConfig, repConfig);
 }
 

See also:
Restoring Log Files
 
 public class NetworkRestore {
     /* The node that needs to be restored. */
     private RepNode repNode;
 
     /* The vlsn that must in the VLSN range of the server. */
     private VLSN minVLSN;
 
     /*
      * Candidate log provider members, for the network restore operation.
      */
     private List<ReplicationNodelogProviders;
 
     /*
      * The log provider actually used to obtain the log files. It must be one
      * of the members from the logProviders list.
      */
     private ReplicationNode logProvider;
 
     /* The current backup attempt. */
     private NetworkBackup backup;
 
     private Logger logger;

    
Creates an instance of NetworkRestore suitable for restoring the logs at this node. After the logs are restored, the node can create a new ReplicatedEnvironment and join the group
    public NetworkRestore() {
    }

    
Initializes this instance for an impending execute() operation.

Parameters:
logException the exception packing information driving the restore operation.
config may contain an explicit list of members.
Returns:
the list of candidate Server instances
Throws:
java.lang.IllegalArgumentException if the configured log providers are invalid
    private List<Serverinit(InsufficientLogException logException,
                              NetworkRestoreConfig config)
        throws IllegalArgumentException {
         = logException.getRepNode();
         = LoggerUtils.getLogger(getClass());
         = logException.getRefreshVLSN();
        int loadThreshold = 0;
        if ((config.getLogProviders() != null) &&
            (config.getLogProviders().size() > 0)) {
            final Set<StringmemberNames = new HashSet<String>();
            for (ReplicationNode node : logException.getLogProviders()) {
                memberNames.add(node.getName());
            }
            for (ReplicationNode node : config.getLogProviders()) {
                if (!memberNames.contains(node.getName())) {
                    throw new  IllegalArgumentException
                        ("Node:" + node.getName() +
                         " is not a suitable member for NetworkRestore." +
                         " It's not a member of logException." +
                         "getLogProviders(): " +
                         Arrays.toString(memberNames.toArray()));
                }
            }
            /*
             * Ignore the load threshold when an explicit member list has been
             * provided.
             */
            loadThreshold = .;
             = config.getLogProviders();
        } else {
             = new LinkedList<ReplicationNode>
                (logException.getLogProviders());
        }
        LoggerUtils.fine
            (.getRepImpl(), "Started network restore");
        /*  List sorted by load below -- low to high */
        List<ServerserverList = new LinkedList<Server>();
        /*
         * Start with an initial threshold of zero to find an idle server. The
         * thresholds will change as the servers are contacted.
         */
        for (ReplicationNode node : ) {
            serverList.add(new Server(nodeloadThreshold));
        }
        return serverList;
    }

    
Restores the log files from one of the members of the replication group.

If config.getLogProviders() returns null, or an empty list, it uses the member that is least busy as the provider of the log files. Otherwise it selects a member from the list, choosing the first member that's available, to provide the log files. If the members in this list are not present in logException.getLogProviders(), it will result in an IllegalArgumentException being thrown. Exceptions handlers for InsufficientLogException will typically use InsufficientLogException.getLogProviders() as the starting point to compute an appropriate list, with which to set up the config argument.

Log files that are currently at the node will be retained if they are part of a consistent set of log files. Obsolete log files are either deleted, or are renamed based on the the configuration of config.getRetainLogFiles().

Parameters:
logException the exception thrown by ReplicatedEnvironment() that necessitated this log refresh operation
config configures the execution of the network restore operation
Throws:
com.sleepycat.je.EnvironmentFailureException if an unexpected, internal or environment-wide failure occurs.
java.lang.IllegalArgumentException if the config is invalid
See also:
NetworkRestoreConfig
    public synchronized
        void execute(InsufficientLogException logException,
                     NetworkRestoreConfig config)
        throws EnvironmentFailureException,
               IllegalArgumentException {
        List<ServerserverList = init(logExceptionconfig);
        /*
         * Loop trying busier servers. It sorts the servers by the number of
         * active feeders at each server and contacts each one in turn, trying
         * increasingly busy servers until it finds a suitable one that will
         * service its request for log files. The same server may be contacted
         * multiple times, since it may become busier between the time it was
         * first contacted and a subsequent attempt.
         */
        while (!serverList.isEmpty()) {
            // Sort by load
            Collections.sort(serverList);
            final List<ServernewServerList = new LinkedList<Server>();
            File envHome = .getRepImpl().getEnvironmentHome();
            for (Server server : serverList) {
                InetSocketAddress serverSocket =
                    server.node.getSocketAddress();
                if (serverSocket.equals(.getSocket())) {
                    /* Cannot restore from yourself. */
                    continue;
                }
                LoggerUtils.info(.getRepImpl(),
                                 "Network restore candidate server: " +
                                 server.node);
                 = server.node;
                final long startTime = System.currentTimeMillis();
                try {
                     = new NetworkBackup
                        (serverSocket,
                         config.getReceiveBufferSize(),
                         envHome,
                         .getNameIdPair(),
                         config.getRetainLogFiles(),
                         server.load,
                         ,
                         .getRepImpl(),
                         .getRepImpl().getFileManager());
                    .execute();
                    LoggerUtils.info
                        (.getRepImpl(),
                         String.format
                         ("Network restore completed from: %s. " +
                          "Elapsed time: %,d s.",
                          server.node,
                          ((System.currentTimeMillis() - startTime) / 1000)));
                    return;
                } catch (DatabaseException e) {
                    /* Likely A malfunctioning server. */
                    LoggerUtils.warning(.getRepImpl(),
                                        "Backup failed from node: " +
                                        server.node + "\n" + e.getMessage());
                } catch (ConnectException e) {
                    /* Move on if the network connection is troublesome. */
                    LoggerUtils.info(.getRepImpl(),
                                     "Backup server node: " + server.node +
                                     " is not available: " + e.getMessage());
                } catch (IOException e) {
                    /* Move on if the network connection is troublesome. */
                    LoggerUtils.warning(.getRepImpl(),
                                        "Backup failed from node: " +
                                        server.node + "\n" + e.getMessage());
                } catch (ServiceConnectFailedException e) {
                    LoggerUtils.warning(.getRepImpl(),
                                        "Backup failed from node: " +
                                        server.node + "\n" + e.getMessage());
                } catch (LoadThresholdExceededException e) {
                    LoggerUtils.info
                        (.getRepImpl(), e.getMessage());
                    /*
                     * Server busier than current load threshold, retain it so
                     * that it can be retried if a less busy server is not
                     * found.
                     */
                    newServerList.add(new Server(server.node,
                                                 e.getActiveServers()));
                } catch (InsufficientVLSNRangeException e) {
                    /* Ignore it in the next round. */
                    LoggerUtils.info(.getRepImpl(),
                                     "Backup failed from node: " +
                                     server.node + " Error: " +
                                     e.getMessage());
                } catch (IllegalArgumentException e) {
                    throw EnvironmentFailureException.unexpectedException(e);
                }
            }
            serverList = newServerList/* New list for the next round. */
        }
        throw EnvironmentFailureException.unexpectedState
            ("Tried and failed with every node");
    }

    

Hidden:
for testing use only
    public NetworkBackup getBackup() {
        return ;
    }

    

Hidden:
for testing use only Returns the member that was used to provide the log files.
    public ReplicationNode getLogProvider() {
        return ;
    }

    
A convenience class to help aggregate server attributes that may be relevant to ordering the servers in terms of their suitability.
    private static class Server implements Comparable<Server> {
        private final ReplicationNode node;
        private final int load;
        public Server(ReplicationNode nodeint load) {
            this. = node;
            this. = load;
        }

        
This method is used in the sort to prioritize servers.
        public int compareTo(Server o) {
            return  - o.load;
        }
        @Override
        public String toString() {
            return .getName();
        }
    }
New to GrepCode? Check out our FAQ X