/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 2002, 2014 Oracle and/or its affiliates. All rights reserved.
*
*/
package com.sleepycat.je.rep.impl;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.UnknownHostException;
import java.util.HashSet;
import java.util.StringTokenizer;
import com.sleepycat.je.config.BooleanConfigParam;
import com.sleepycat.je.config.ConfigParam;
import com.sleepycat.je.config.DurationConfigParam;
import com.sleepycat.je.config.EnvironmentParams;
import com.sleepycat.je.config.IntConfigParam;
import com.sleepycat.je.config.LongConfigParam;
import com.sleepycat.je.rep.NodeType;
import com.sleepycat.je.rep.ReplicationConfig;
import com.sleepycat.je.rep.ReplicationMutableConfig;
import com.sleepycat.je.rep.ReplicationNetworkConfig;
import com.sleepycat.je.rep.ReplicationSSLConfig;
import com.sleepycat.je.rep.util.DbResetRepGroup;
import com.sleepycat.je.rep.utilint.RepUtils;
import com.sleepycat.je.rep.utilint.net.SSLChannelFactory;
public class RepParams {
/*
* Note: all replicated parameters should start with
* EnvironmentParams.REP_PARAM_PREFIX, which is "je.rep.",
* see SR [#19080].
*/
/**
* @hidden
* Name of a java System property (boolean) which can be turned on in order
* to avoid input validation checks on node names. This is undocumented.
*
* Generally users should not skip validation, because there are a few
* kinds of punctuation characters that would cause problems if they were
* allowed in node names. But in the past users might have inadvertantly
* created node names that do not conform to the new, stricter rules. In
* that case they would not be able to upgrade to the newer version of JE
* that now includes this checking.
*
* This flag actually applies to the group name too. But for group names
* the new rules are actually less strict than they used to be, so there
* should be no problem.
*/
public static final String SKIP_NODENAME_VALIDATION =
"je.rep.skipNodenameValidation";
/**
* A JE/HA configuration parameter describing an Identifier name.
*/
static public class IdentifierConfigParam extends ConfigParam {
private static final String DEBUG_NAME =
IdentifierConfigParam.class.getName();
public IdentifierConfigParam(String configName,
String defaultValue,
boolean mutable,
boolean forReplication) {
super(configName, defaultValue, mutable, forReplication);
}
@Override
public void validateValue(String value) {
if (Boolean.getBoolean(SKIP_NODENAME_VALIDATION)) {
return;
}
if ((value == null) || (value.length() == 0)) {
throw new IllegalArgumentException
(DEBUG_NAME + ": a value is required");
}
for (char c : value.toCharArray()) {
if (!isValid(c)) {
throw new IllegalArgumentException
(DEBUG_NAME + ": " + name + ", must consist of " +
"letters, digits, hyphen, underscore, period.");
}
}
}
private boolean isValid(char c) {
if (Character.isLetterOrDigit(c) ||
c == '-' ||
c == '_' ||
c == '.') {
return true;
}
return false;
}
}
/*
* Replication group-wide properties. These properties are candidates for
* consistency checking whenever there is a handshake between a master and
* replica.
*/
/** Names the Replication group. */
public static final ConfigParam GROUP_NAME =
new IdentifierConfigParam(ReplicationConfig.GROUP_NAME,
"DefaultGroup", // default
false, // mutable
true); // forReplication
/**
* The maximum amount of time the replication group guarantees preservation
* of the log files constituting the replication stream. After this period
* of time, nodes are free to do log cleaning and to remove log files
* earlier than this period. If a node has crashed and does not re-join the
* group within this timeout period it may need to perform a network
* restore operation to catch up.
*/
public static final DurationConfigParam REP_STREAM_TIMEOUT =
new DurationConfigParam(ReplicationConfig.REP_STREAM_TIMEOUT,
null, // min
null, // max
"24 h", // default
false, // mutable
true);
/**
* The minimum number of, most recent, VLSNs that are retained as part of
* the replication stream. This ensures that any requests to sync in the
* current vlsn range between: [ VLSNRange.getLast() - MIN_RETAINED_VLSNS
* .. VLSNRange.getLast ] are guaranteed to succeed as long as there is a
* syncable VLSN in this range.
*
* The default value of 200000 vlsns, roughly corresponds to 10K of records
* each committed in its own transaction. Assuming an average record size
* of 1K, this represents ~100MB of retained storage.
*
* Note that this value must be set consistently across all the RNs in the
* replication group.
*/
public static final IntConfigParam MIN_RETAINED_VLSNS =
new IntConfigParam(EnvironmentParams.REP_PARAM_PREFIX +
"minRetainedVLSNs",
0, // min
null, // max
200000, // default
false, // mutable
true); // forReplication
/**
* @see ReplicationConfig#REPLICA_RECEIVE_BUFFER_SIZE
*/
public static final IntConfigParam REPLICA_RECEIVE_BUFFER_SIZE =
new IntConfigParam(ReplicationConfig.REPLICA_RECEIVE_BUFFER_SIZE,
0, // min
null, // max
1048576, // default
false, // mutable
true); // forReplication
/**
* The size of the message queue used for communication between the thread
* reading the replication stream and the thread doing the replay. The
* default buffer size has been chosen to hold 500 single operation
* transactions (the ln + commit record) assuming 1K sized LN record.
*
* Larger values of buffer size may result in higher peak memory
* utilization, due to a larger number of LNs sitting in the queue. The
* size of the queue itself is unlikely to be an issue, since it's tiny
* relative to cache sizes. At 1000, 1kbyte LNs it raises the peak
* utilization by 1MB which for most apps is an insignificant rise in the
* peak.
*
* Note that the parameter is lazily mutable, that is, the change will take
* effect the next time the node transitions to a replica state.
*/
public static final IntConfigParam REPLICA_MESSAGE_QUEUE_SIZE =
new IntConfigParam(EnvironmentParams.REP_PARAM_PREFIX +
"replicaMessageQueueSize",
1, // min
null, // max
1000, // default
true, // mutable
true); // forReplication
/**
* The lock timeout for replay transactions.
*/
public static final DurationConfigParam REPLAY_TXN_LOCK_TIMEOUT =
new DurationConfigParam(ReplicationConfig.REPLAY_TXN_LOCK_TIMEOUT,
"1 ms", // min
"75 min", // max
"500 ms", // default
false, // mutable
true); // forReplication
/**
* @see ReplicationConfig#ENV_SETUP_TIMEOUT
*/
public static final DurationConfigParam ENV_SETUP_TIMEOUT =
new DurationConfigParam
(ReplicationConfig.ENV_SETUP_TIMEOUT,
null, // min
null, // max
"10 h", // default 10 hrs
false, // mutable
true);
/**
* @see ReplicationConfig#ENV_CONSISTENCY_TIMEOUT
*/
public static final DurationConfigParam
ENV_CONSISTENCY_TIMEOUT =
new DurationConfigParam(ReplicationConfig.ENV_CONSISTENCY_TIMEOUT,
"10 ms", // min
null, // max
"5 min", // default
false, // mutable
true);
/**
* @see ReplicationConfig#ENV_UNKNOWN_STATE_TIMEOUT
*/
public static final DurationConfigParam ENV_UNKNOWN_STATE_TIMEOUT =
new DurationConfigParam
(ReplicationConfig.ENV_UNKNOWN_STATE_TIMEOUT,
null, // min
null, // max
"0 s", // default
false, // mutable
true);
/**
* @see ReplicationConfig#REPLICA_ACK_TIMEOUT
*/
public static final DurationConfigParam REPLICA_ACK_TIMEOUT =
new DurationConfigParam(ReplicationConfig.REPLICA_ACK_TIMEOUT,
"10 ms", // min
null, // max
"5 s", // default
false, // mutable
true); // forReplication
/**
* @see ReplicationConfig#INSUFFICIENT_REPLICAS_TIMEOUT
*/
public static final DurationConfigParam INSUFFICIENT_REPLICAS_TIMEOUT =
new DurationConfigParam(ReplicationConfig.INSUFFICIENT_REPLICAS_TIMEOUT,
"10 ms", // min
null, // max
"10 s", // default
false, // mutable
true); // forReplication
/**
* Internal parameter enable use of the group ack message. It's off by
* default for now until we get to a release in which we can change the HA
* protocol version number.
*/
public static final BooleanConfigParam ENABLE_GROUP_ACKS =
new BooleanConfigParam(EnvironmentParams.REP_PARAM_PREFIX +
"enableGroupAcks",
false, // default
false, // mutable
true);
/**
* The maximum message size which will be accepted by a node (to prevent
* DOS attacks). While the default shown here is 0, it dynamically
* calculated when the node is created and is set to the half of the
* environment cache size. The cache size is mutable, but changing the
* cache size at run time (after environment initialization) will not
* change the value of this parameter. If a value other than cache size /
* 2 is desired, this non-mutable parameter should be specified at
* initialization time.
*/
public static final LongConfigParam MAX_MESSAGE_SIZE =
new LongConfigParam(ReplicationConfig.MAX_MESSAGE_SIZE,
Long.valueOf(1 << 18), // min (256KB)
Long.valueOf(Long.MAX_VALUE), // max
Long.valueOf(0), // default (cachesize / 2)
false, // mutable
true); // forReplication
/**
* Identifies the default consistency policy used by a replica. Only two
* policies are meaningful as properties denoting environment level default
* policies: NoConsistencyRequiredPolicy and TimeConsistencyPolicy. They
* can be specified as: NoConsistencyRequiredPolicy or
* TimeConsistencyPolicy(,). For example, a time
* based consistency policy with a lag of 1 second and a timeout of 1 hour
* is denoted by the string: TimeConsistencyPolicy(1000,3600000)
*/
public static final ConfigParam CONSISTENCY_POLICY =
new ConfigParam(ReplicationConfig.CONSISTENCY_POLICY,
// Default lag of 1 sec, and timeout of 1 hour
"TimeConsistencyPolicy(1 s,1 h)",
false, // mutable
true) { // for Replication
@Override
public void validateValue(String propertyValue)
throws IllegalArgumentException {
/* Evaluate for the checking side-effect. */
RepUtils.getReplicaConsistencyPolicy(propertyValue);
}
};
/* The ports used by a replication group */
/**
* The port used for replication.
*/
public static final IntConfigParam DEFAULT_PORT =
new IntConfigParam(ReplicationConfig.DEFAULT_PORT,
Integer.valueOf(1024), // min
Integer.valueOf(Short.MAX_VALUE), // max
Integer.valueOf(5001), // default
false, // mutable
true); // forReplication
/**
* Names the host (or interface) and port associated with the node in the
* replication group, e.g. je.rep.nodeHostPort=foo.com:5001
*/
public static final ConfigParam NODE_HOST_PORT =
new ConfigParam(ReplicationConfig.NODE_HOST_PORT,
"localhost", // default
false, // mutable
true) { // forReplication
@Override
public void validateValue(String hostAndPort)
throws IllegalArgumentException {
if ((hostAndPort == null) || (hostAndPort.length() == 0)) {
throw new IllegalArgumentException
("The value cannot be null or zero length: " + name);
}
int colonToken = hostAndPort.indexOf(":");
String hostName = (colonToken >= 0) ?
hostAndPort.substring(0,colonToken) :
hostAndPort;
ServerSocket testSocket = null;
try {
testSocket = new ServerSocket();
/* The bind will fail if the hostName does not name this m/c.*/
testSocket.bind(new InetSocketAddress(hostName, 0));
testSocket.close();
} catch (UnknownHostException e) {
throw new IllegalArgumentException
("Property: " + name +
" Invalid hostname: " + hostName, e);
} catch (IOException e) {
/*
* Server socket could not be bound to any port. Hostname is
* not associated with this m/c.
*/
throw new IllegalArgumentException
("Property: " + name +
" Invalid hostname: " + hostName, e);
}
if (colonToken >= 0) {
validatePort(hostAndPort.substring(colonToken+1));
}
}
};
/*
* The Name uniquely identifies this node within the replication group.
*/
public static final ConfigParam NODE_NAME =
new IdentifierConfigParam(ReplicationConfig.NODE_NAME,
"DefaultRepNodeName",// default
false, // mutable
true); // forReplication
/*
* Identifies the type of the node.
*/
public static final EnumConfigParam NODE_TYPE =
new EnumConfigParam(ReplicationConfig.NODE_TYPE,
NodeType.ELECTABLE, // default
false, // mutable
true,
NodeType.class);
/*
* Associated a priority with this node. The priority is used during
* elections to favor one node over another. All other considerations being
* equal, the priority is used as a tie-breaker; the node with the higher
* priority is selected as the master.
*/
public static final IntConfigParam NODE_PRIORITY =
new IntConfigParam(ReplicationMutableConfig.NODE_PRIORITY,
Integer.valueOf(0), // min
Integer.valueOf(Integer.MAX_VALUE), // max
Integer.valueOf(1), // default
true, // mutable
true); // forReplication
/*
* Identifies the Primary node in a two node group.
*/
public static final BooleanConfigParam DESIGNATED_PRIMARY =
new BooleanConfigParam(ReplicationMutableConfig.DESIGNATED_PRIMARY,
false, // default
true, // mutable
true);
/*
* An internal option used to control the use of Nagle's algorithm
* on feeder connections. A value of true disables use of Nagle's algorithm
* and causes output to be sent immediately without delay.
*/
public static final BooleanConfigParam FEEDER_TCP_NO_DELAY =
new BooleanConfigParam(EnvironmentParams.REP_PARAM_PREFIX +
"feederTcpNoDelay",
true, // default
false, // mutable
true);
/**
* The time interval in nanoseconds during which records from a feeder may
* be batched before being written to the network.
*
* Larger values can result in fewer network packets and lower interrupt
* processing overheads. Since the grouping is only done when the feeder
* knows that the replica is not completely in sync, it's unlikely to have
* an adverse impact on overall throughput. Consequently this parameter is
* retained as an internal tuning knob.
*
* The HEARTBEAT_INTERVAL parameter serves as a ceiling on this time
* interval. Parameter values larger than HEARTBEAT_INTERVAL are truncated
* to HEARTBEAT_INTERVAL.
*/
public static final IntConfigParam FEEDER_BATCH_NS =
new IntConfigParam(EnvironmentParams.REP_PARAM_PREFIX +
"feederBatchNs",
Integer.valueOf(0), // min
Integer.valueOf(Integer.MAX_VALUE),// max
Integer.valueOf(1000000), // default 1 ms
true, // mutable
true); // forReplication
/**
* The size in KB used to batch outgoing feeder records. Upon overflow the
* existing buffer contents are written to the network and a new batch is
* initiated. The default value is 64K to take advantage of networks that
* support jumbo frames.
*/
public static final IntConfigParam FEEDER_BATCH_BUFF_KB =
new IntConfigParam(EnvironmentParams.REP_PARAM_PREFIX +
"feederBatchBuffKb",
Integer.valueOf(4), // min
Integer.valueOf(Integer.MAX_VALUE),// max
Integer.valueOf(64), // default 64K
true, // mutable
true); // forReplication
/**
* @see ReplicationMutableConfig#ELECTABLE_GROUP_SIZE_OVERRIDE
*/
public static final IntConfigParam ELECTABLE_GROUP_SIZE_OVERRIDE =
new IntConfigParam(ReplicationMutableConfig.
ELECTABLE_GROUP_SIZE_OVERRIDE,
Integer.valueOf(0), // min
Integer.valueOf(Integer.MAX_VALUE),// max
Integer.valueOf(0), // default
true, // mutable
true); // forReplication
/**
* An internal option, accessed only via the utility
* {@link DbResetRepGroup} utility, to reset a replication group to a
* single new member when the replicated environment is opened.
*/
public static final BooleanConfigParam RESET_REP_GROUP =
new BooleanConfigParam(EnvironmentParams.REP_PARAM_PREFIX +
"resetRepGroup",
false, // default
false, // mutable
true);
/**
* An internal option, used with {@link #RESET_REP_GROUP}, that causes the
* reset of the replication group to retain the original group UUID and to
* not truncate the VLSN index. Use this option when converting a
* SECONDARY node to an ELECTABLE node when recovering a replication group.
*/
public static final BooleanConfigParam RESET_REP_GROUP_RETAIN_UUID =
new BooleanConfigParam(EnvironmentParams.REP_PARAM_PREFIX +
"resetRepGroupRetainUUID",
false, // default
false, // mutable
true);
/**
* An internal option to allow converting an ELECTABLE node to a SECONDARY
* node by ignoring the electable node ID stored in the local rep group
* DB.
*/
public static final BooleanConfigParam IGNORE_SECONDARY_NODE_ID =
new BooleanConfigParam(EnvironmentParams.REP_PARAM_PREFIX +
"ignoreSecondaryNodeId",
false, // default
false, // mutable
true);
/*
* Sets the maximum allowable skew between a Feeder and its replica. The
* clock skew is checked as part of the handshake when the Replica
* establishes a connection to its Feeder.
*/
public static final DurationConfigParam MAX_CLOCK_DELTA =
new DurationConfigParam(ReplicationConfig.MAX_CLOCK_DELTA,
null, // min
"1 min", // max
"2 s", // default
false, // mutable
true); // forReplication
/*
* The list of helper node and port pairs.
*/
public static final ConfigParam HELPER_HOSTS =
new ConfigParam(ReplicationConfig.HELPER_HOSTS,
"", // default
true, // mutable
true) { // forReplication
@Override
public void validateValue(String hostPortPairs)
throws IllegalArgumentException {
if ((hostPortPairs == null) || (hostPortPairs.length() == 0)) {
return;
}
HashSet hostPortSet = new HashSet();
for (StringTokenizer tokenizer =
new StringTokenizer(hostPortPairs,",");
tokenizer.hasMoreTokens();) {
try {
String hostPortPair = tokenizer.nextToken();
if (!hostPortSet.add(hostPortPair)) {
throw new IllegalArgumentException
("Property: " + name +
" Duplicate specification: " + hostPortPair);
}
validateHostAndPort(hostPortPair);
} catch (IllegalArgumentException iae) {
throw new IllegalArgumentException
("Property: " + name + "Error: " + iae.getMessage(),
iae);
}
}
}
};
/* Heartbeat interval in milliseconds. */
public static final IntConfigParam HEARTBEAT_INTERVAL =
new IntConfigParam
(EnvironmentParams.REP_PARAM_PREFIX + "heartbeatInterval",
Integer.valueOf(1000),// min
null, // max
Integer.valueOf(1000),// default
false, // mutable
true); // forReplication
/* Replay Op Count after which we clear the DbTree cache. */
public static final IntConfigParam DBTREE_CACHE_CLEAR_COUNT =
new IntConfigParam
(EnvironmentParams.REP_PARAM_PREFIX + "dbIdCacheOpCount",
Integer.valueOf(1), // min
null, // max
Integer.valueOf(5000), // default
false, // mutable
true); // forReplication
public static final IntConfigParam VLSN_STRIDE =
new IntConfigParam(EnvironmentParams.REP_PARAM_PREFIX + "vlsn.stride",
Integer.valueOf(1), // min
null, // max
Integer.valueOf(10), // default
false, // mutable
true); // forReplication
public static final IntConfigParam VLSN_MAX_MAP =
new IntConfigParam
(EnvironmentParams.REP_PARAM_PREFIX + "vlsn.mappings",
Integer.valueOf(1), // min
null, // max
Integer.valueOf(1000), // default
false, // mutable
true); // forReplication
public static final IntConfigParam VLSN_MAX_DIST =
new IntConfigParam
(EnvironmentParams.REP_PARAM_PREFIX + "vlsn.distance",
Integer.valueOf(1), // min
null, // max
Integer.valueOf(100000), // default
false, // mutable
true); // forReplication
/*
* Internal testing use only: Simulate a delay in the replica loop for test
* purposes. The value is the delay in milliseconds.
*/
public static final IntConfigParam TEST_REPLICA_DELAY =
new IntConfigParam
(EnvironmentParams.REP_PARAM_PREFIX + "test.replicaDelay",
Integer.valueOf(0), // min
Integer.valueOf(Integer.MAX_VALUE), // max
Integer.valueOf(0), // default
false, // mutable
true); // forReplication
/*
* Sets the VLSNIndex cache holding recent log items in support of the
* feeders. The size must be a power of two.
*/
public static final IntConfigParam VLSN_LOG_CACHE_SIZE =
new IntConfigParam
(EnvironmentParams.REP_PARAM_PREFIX + "vlsn.logCacheSize",
Integer.valueOf(0), // min
Integer.valueOf(1<<10), // max
Integer.valueOf(32), // default
false, // mutable
true); // forReplication
/*
* The socket timeout value used by a Replica when it opens a new
* connection to establish a replication stream with a feeder.
*/
public static final DurationConfigParam REPSTREAM_OPEN_TIMEOUT =
new DurationConfigParam
(EnvironmentParams.REP_PARAM_PREFIX + "repstreamOpenTimeout",
null, // min
"5 min", // max
"5 s", // default
false, // mutable
true); // forReplication
/*
* The socket timeout value used by Elections agents when they open
* sockets to communicate with each other using the Elections protocol.
*/
public static final DurationConfigParam ELECTIONS_OPEN_TIMEOUT =
new DurationConfigParam
(EnvironmentParams.REP_PARAM_PREFIX + "electionsOpenTimeout",
null, // min
"1 min", // max
"10 s", // default
false, // mutable
true); // forReplication
/*
* The maximum amount of time a Learner or Acceptor agent will wait for
* input on a network connection, while listening for a message before
* timing out. This timeout applies to the Elections protocol.
*/
public static final DurationConfigParam ELECTIONS_READ_TIMEOUT =
new DurationConfigParam
(EnvironmentParams.REP_PARAM_PREFIX + "electionsReadTimeout",
null, // min
"1 min", // max
"10 s", // default
false, // mutable
true); // forReplication
/**
* The master re-broadcasts the results of an election with this period.
*/
public static final DurationConfigParam
ELECTIONS_REBROADCAST_PERIOD =
new DurationConfigParam
(ReplicationConfig.ELECTIONS_REBROADCAST_PERIOD,
null, // min
null, // max
"1 min", // default
false, // mutable
true);
/**
* @see ReplicationConfig#ELECTIONS_PRIMARY_RETRIES
*/
public static final IntConfigParam ELECTIONS_PRIMARY_RETRIES =
new IntConfigParam(ReplicationConfig.ELECTIONS_PRIMARY_RETRIES,
0,
Integer.MAX_VALUE,
2,
false,
true);
/*
* Socket open timeout for use with the RepGroupProtocol.
*/
public static final DurationConfigParam REP_GROUP_OPEN_TIMEOUT =
new DurationConfigParam
(EnvironmentParams.REP_PARAM_PREFIX + "repGroupOpenTimeout",
null, // min
"1 min", // max
"10 s", // default
false, // mutable
true); // forReplication
/*
* Socket read timeout for use with the RepGroupProtocol.
*/
public static final DurationConfigParam REP_GROUP_READ_TIMEOUT =
new DurationConfigParam
(EnvironmentParams.REP_PARAM_PREFIX + "repGroupReadTimeout",
null, // min
"1 min", // max
"10 s", // default
false, // mutable
true); // forReplication
/*
* Socket open timeout for use with the Monitor Protocol.
*/
public static final DurationConfigParam MONITOR_OPEN_TIMEOUT =
new DurationConfigParam
(EnvironmentParams.REP_PARAM_PREFIX + "monitorOpenTimeout",
null, // min
"1 min", // max
"10 s", // default
false, // mutable
true); // forReplication
/*
* Socket read timeout for use with the MonitorProtocol.
*/
public static final DurationConfigParam MONITOR_READ_TIMEOUT =
new DurationConfigParam
(EnvironmentParams.REP_PARAM_PREFIX + "monitorReadTimeout",
null, // min
"1 min", // max
"10 s", // default
false, // mutable
true); // forReplication
/**
* @see ReplicationConfig#REPLICA_TIMEOUT
*/
public static final DurationConfigParam REPLICA_TIMEOUT =
new DurationConfigParam(ReplicationConfig.REPLICA_TIMEOUT,
"2 s", // min
null, // max
"30 s", // default
false, // mutable
true); // forReplication
/* @see ReplicationConfig#REPLAY_MAX_OPEN_DB_HANDLES */
public static final IntConfigParam REPLAY_MAX_OPEN_DB_HANDLES =
new IntConfigParam(ReplicationMutableConfig.REPLAY_MAX_OPEN_DB_HANDLES,
Integer.valueOf(1), // min
Integer.valueOf(Integer.MAX_VALUE), // max
Integer.valueOf(10), // default
true, // mutable
true); // forReplication
/* @see ReplicationConfig#REPLAY_DB_HANDLE_TIMEOUT */
public static final DurationConfigParam REPLAY_DB_HANDLE_TIMEOUT =
new DurationConfigParam(ReplicationConfig.REPLAY_DB_HANDLE_TIMEOUT,
"1 s", // min
null, // max
"30 s", // default
true, // mutable
true); // forReplication
/* @see ReplicationConfig#REPLICA_MAX_GROUP_COMMIT */
public static final IntConfigParam REPLICA_MAX_GROUP_COMMIT =
new IntConfigParam(ReplicationConfig.REPLICA_MAX_GROUP_COMMIT,
Integer.valueOf(0), // min
null, // max
Integer.valueOf(200), // default
false, // mutable
true); // forReplication
/* @see ReplicationConfig#REPLICA_GROUP_COMMIT_INTERVAL */
public static final DurationConfigParam REPLICA_GROUP_COMMIT_INTERVAL =
new DurationConfigParam(ReplicationConfig.REPLICA_GROUP_COMMIT_INTERVAL,
"0 ms", // min
null, // max
"3 ms", // default
false, // mutable
true); // forReplication
/*
* The number of heartbeat responses that must be detected as missing
* during an otherwise idle period before the Feeder shuts down the
* connection with the Replica.
*
* This value provides the basis for the "read timeout" used by the Feeder
* when communicating with the Replica. The timeout is calculated as
* FEEDER_HEARTBEAT_TIMEOUT * HEARTBEAT_INTERVAL. Upon a timeout the Feeder
* closes the connection.
*
* Reducing this value permits the master to discover failed Replicas
* faster. However, it increases the chances of false positives as well, if
* the network is experiencing transient problems from which it might
* just recover.
*/
public static final IntConfigParam FEEDER_HEARTBEAT_TIMEOUT =
new IntConfigParam
(EnvironmentParams.REP_PARAM_PREFIX + "feederHeartbeatTrigger",
Integer.valueOf(0), // min
Integer.valueOf(Integer.MAX_VALUE), // max
Integer.valueOf(4), // default
false, // mutable
true);
/**
* Used to force setting of SO_REUSEADDR to true on the HA server socket
* when it binds to its port.
*
* Note that the default is false, meaning that the socket has the
* system-specific default setting associated with it. We set it to true
* primarily in unit tests where the interacting HA processes are all on
* the same machine and use of this option is safe.
*
* This option is currently intended just for internal test use.
*/
public static final BooleanConfigParam SO_REUSEADDR =
new BooleanConfigParam
(EnvironmentParams.REP_PARAM_PREFIX + "soReuseAddr",
false, // default
false, // mutable
true);
/**
* This option was motivated by the BDA. The BDA uses IB for intra-rack
* node communications and 10gigE for inter-rack node communications. DNS
* is used to map the hostname to different IP addresses depending on
* whether the hostname was resolved from within the rack or outside it.
* The host thus gets HA traffic on both the IB and 10gigE interfaces and
* therefore needs to listen on both interfaces. It does so binding its
* socket using a wild card address when this option iks turned on.
*
* @see ReplicationConfig#BIND_INADDR_ANY
*/
public static final BooleanConfigParam BIND_INADDR_ANY =
new BooleanConfigParam
(ReplicationConfig.BIND_INADDR_ANY,
false, // default
false, // mutable
true);
/**
* Determines how long to wait for a bound socket to come free. This option
* can be useful when dealing with sockets in the TIME_WAIT state to come
* free so they can be reused. Attempts are made to retry binding to this
* period at intervals of 1 second until the port is bound successfully, or
* this wait period is exceeded.
*
* A value of zero means that there are no retries. It does not make sense
* to wait too much longer than the 2 min TIME_WAIT period, but we allow
* waiting as long as 2.5 min to account for race conditions.
*
* This option is currently intended just for internal test use.
*/
public static final IntConfigParam SO_BIND_WAIT_MS =
new IntConfigParam
(EnvironmentParams.REP_PARAM_PREFIX + "retrySocketBind",
Integer.valueOf(0), // min
Integer.valueOf(150 * 1000), // max
Integer.valueOf(0), // default
false, // mutable
true);
/**
* @see ReplicationConfig#FEEDER_TIMEOUT
*/
public static final DurationConfigParam FEEDER_TIMEOUT =
new DurationConfigParam(ReplicationConfig.FEEDER_TIMEOUT,
"2 s", // min
null, // max
"30 s", // default
false, // mutable
true); // forReplication
/**
* Used to log an info message when a commit log record exceeds this
* time interval from the time it was created, to the time it was written
* out to the network.
*/
public static final DurationConfigParam TRANSFER_LOGGING_THRESHOLD =
new DurationConfigParam
(EnvironmentParams.REP_PARAM_PREFIX + "transferLoggingThreshold",
"1 ms", // min
null, // max
"5 s", // default
false, // mutable
true); // forReplication
/**
* Used to log an info message when the time taken to replay a single log
* entry at a replica exceeds this threshold.
*/
public static final DurationConfigParam REPLAY_LOGGING_THRESHOLD =
new DurationConfigParam
(EnvironmentParams.REP_PARAM_PREFIX + "replayLoggingThreshold",
"1 ms", // min
null, // max
"5 s", // default
false, // mutable
true); // forReplication
/**
* Changes the notion of an ack. When set to true, a replica is considered
* to have acknowledged a commit as soon as the feeder has written the
* commit record to the network. That is, it does not wait for the replica
* to actually acknowledge the commit via a return message. This permits
* the master to operate in a more async manner relative to the replica
* provide for higher throughput.
*
* This config parameter is internal.
*/
public static final BooleanConfigParam COMMIT_TO_NETWORK =
new BooleanConfigParam
(EnvironmentParams.REP_PARAM_PREFIX + "commitToNetwork",
false, // default
false, // mutable
true);
public static final DurationConfigParam PRE_HEARTBEAT_TIMEOUT =
new DurationConfigParam
(EnvironmentParams.REP_PARAM_PREFIX + "preHeartbeatTimeoutMs",
"1 s", // min
null, // max
"60 s", // default
false, // mutable
true);
/**
* Verifies that the port is a reasonable number. The port must be outside
* the range of "Well Known Ports" (zero through 1024).
*
* @param portString the string representing the port.
*/
private static void validatePort(String portString)
throws IllegalArgumentException {
try {
int port = Integer.parseInt(portString);
if ((port <= 0) || (port > 0xffff)) {
throw new IllegalArgumentException
("Invalid port number: " + portString);
}
if (port <= 1023) {
throw new IllegalArgumentException
("Port number " + port +
" is invalid because the port must be outside the range of \"well known\" ports");
}
} catch (NumberFormatException e) {
throw new IllegalArgumentException
("Invalid port number: " + portString);
}
}
/**
* Validates that the hostPort is a string of the form:
*
* hostName[:port]
*
* @param hostAndPort
* @throws IllegalArgumentException
*/
private static void validateHostAndPort(String hostAndPort)
throws IllegalArgumentException {
int colonToken = hostAndPort.indexOf(":");
String hostName = (colonToken >= 0) ?
hostAndPort.substring(0,colonToken) :
hostAndPort;
if ("".equals(hostName)) {
throw new IllegalArgumentException("missing hostname");
}
try {
InetAddress.getByName(hostName);
} catch (UnknownHostException e) {
throw new IllegalArgumentException
("Invalid hostname: " + e.getMessage());
}
if (colonToken >= 0) {
validatePort(hostAndPort.substring(colonToken+1));
}
}
/**
* @see ReplicationConfig#TXN_ROLLBACK_LIMIT
*/
public static final IntConfigParam TXN_ROLLBACK_LIMIT =
new IntConfigParam(ReplicationConfig.
TXN_ROLLBACK_LIMIT,
Integer.valueOf(0), // min
Integer.valueOf(Integer.MAX_VALUE),// max
Integer.valueOf(10), // default
false, // mutable
true); // forReplication
/**
* @see ReplicationConfig#RUN_LOG_FLUSH_TASK
*/
public static final BooleanConfigParam RUN_LOG_FLUSH_TASK =
new BooleanConfigParam(ReplicationMutableConfig.RUN_LOG_FLUSH_TASK,
true, // default
true, // mutable
true); // forReplication
/**
* @see ReplicationConfig#LOG_FLUSH_TASK_INTERVAL
*/
public static final DurationConfigParam LOG_FLUSH_TASK_INTERVAL =
new DurationConfigParam
(ReplicationMutableConfig.LOG_FLUSH_TASK_INTERVAL,
"1 s", // min
null, // max
"5 min", // default
true, // mutable
true); // forReplication
/**
* @see ReplicationConfig#ALLOW_UNKNOWN_STATE_ENV_OPEN
*/
@SuppressWarnings({ "javadoc", "deprecation" })
public static final BooleanConfigParam ALLOW_UNKNOWN_STATE_ENV_OPEN =
new BooleanConfigParam(ReplicationConfig.ALLOW_UNKNOWN_STATE_ENV_OPEN,
false, // default
false, // mutable
true);
/**
* If true, the replica runs with this property will not join the
* replication group.
*/
public static final BooleanConfigParam DONT_JOIN_REP_GROUP =
new BooleanConfigParam(EnvironmentParams.REP_PARAM_PREFIX +
"dontJoinRepGroup",
false,
false,
true);
/**
* Internal parameter to preserve record version (VLSN). Is immutable
* forever, i.e., it may not be changed after the environment has been
* created. It has the following impacts:
*
* . The VLSN is stored with the LN in the Btree and is available via the
* CursorImpl API.
* . The VLSN is included when migrating an LN during log cleaning.
*
* FUTURE: Expose this in ReplicationConfig and improve doc if we make
* record versions part of the public API.
*/
public static final BooleanConfigParam PRESERVE_RECORD_VERSION =
new BooleanConfigParam(EnvironmentParams.REP_PARAM_PREFIX +
"preserveRecordVersion",
false, // default
false, // mutable
true); // forReplication
/**
* Whether to cache the VLSN in the BIN after the LN has been stripped by
* eviction, unless caching is explicitly disabled using the
* CACHE_RECORD_VERSION setting.
*
* This setting has no impact if PRESERVE_RECORD_VERSION is not also
* enabled.
*
* FUTURE: Expose this in ReplicationConfig and improve doc if we make
* record versions part of the public API.
*/
public static final BooleanConfigParam CACHE_RECORD_VERSION =
new BooleanConfigParam(EnvironmentParams.REP_PARAM_PREFIX +
"cacheRecordVersion",
true, // default
false, // mutable
true); // forReplication
/**
* The initial number of bytes per record version (per VLSN sequence) in
* the record version cache. The default value, 5, is appropriate for data
* set sizes roughly from 1 to 100 billion. A smaller value may be
* configured to save memory for smaller data sets. A larger value may be
* configured to avoid mutation of the cache as the data set grows.
*
* This setting has no impact unless CACHE_RECORD_VERSION and
* PRESERVE_RECORD_VERSION are not also enabled.
*
* FUTURE: Expose this in ReplicationConfig and improve doc if we make
* record versions part of the public API.
*/
public static final IntConfigParam CACHED_RECORD_VERSION_MIN_LENGTH =
new IntConfigParam(EnvironmentParams.REP_PARAM_PREFIX +
"cachedRecordVersionMinLength",
Integer.valueOf(1), // min
Integer.valueOf(8), // max
Integer.valueOf(5), // default
false, // mutable
true); // forReplication
/**
* @see ReplicationConfig#PROTOCOL_OLD_STRING_ENCODING
* TODO: Change default to false in JE 5.1.
*/
public static final BooleanConfigParam PROTOCOL_OLD_STRING_ENCODING =
new BooleanConfigParam(ReplicationConfig.PROTOCOL_OLD_STRING_ENCODING,
true, // default
false, // mutable
true); // forReplication
/**
* A JE/HA configuration parameter specifying a data channel type
*/
static public class ChannelTypeConfigParam extends ConfigParam {
public static final String BASIC = "basic";
public static final String SSL = "ssl";
public static final String CUSTOM = "custom";
private static final String DEBUG_NAME =
ChannelTypeConfigParam.class.getName();
public ChannelTypeConfigParam(String configName,
String defaultValue,
boolean mutable,
boolean forReplication) {
super(configName, defaultValue, mutable, forReplication);
}
@Override
public void validateValue(String value) {
if (value == null) {
throw new IllegalArgumentException
(DEBUG_NAME + ": a value is required");
}
if (!(BASIC.equals(value) ||
SSL.equals(value) ||
CUSTOM.equals(value))) {
throw new IllegalArgumentException
(DEBUG_NAME + ": " + value + " a not a valid value");
}
}
}
/**
* Replication data channel factory configuration
* @see ReplicationNetworkConfig#CHANNEL_TYPE
*/
public static final ConfigParam CHANNEL_TYPE =
new ChannelTypeConfigParam(
ReplicationNetworkConfig.CHANNEL_TYPE,
ChannelTypeConfigParam.BASIC, // default
false, // mutable
true); // forReplication
/**
* Replication data channel logging identifier.
* @see ReplicationNetworkConfig#CHANNEL_LOG_NAME
*/
public static final ConfigParam CHANNEL_LOG_NAME =
new ConfigParam(
ReplicationNetworkConfig.CHANNEL_LOG_NAME,
"", // default
false, // mutable
true); // forReplication
/**
* Data channel factory class
* @see ReplicationNetworkConfig#CHANNEL_FACTORY_CLASS
*/
public static final ConfigParam CHANNEL_FACTORY_CLASS =
new ConfigParam(ReplicationNetworkConfig.CHANNEL_FACTORY_CLASS,
"", // default
false, // mutable
true); // forReplication
/**
* Data channel factory parameters
* @see ReplicationNetworkConfig#CHANNEL_FACTORY_PARAMS
*/
public static final ConfigParam CHANNEL_FACTORY_PARAMS =
new ConfigParam(ReplicationNetworkConfig.CHANNEL_FACTORY_PARAMS,
"", // default
false, // mutable
true); // forReplication
/**
* SSL KeyStore file
* @see ReplicationSSLConfig#SSL_KEYSTORE_FILE
*/
public static final ConfigParam SSL_KEYSTORE_FILE =
new ConfigParam(ReplicationSSLConfig.SSL_KEYSTORE_FILE,
"", // default
false, // mutable
true); // forReplication
/**
* SSL KeyStore password
* @see ReplicationSSLConfig#SSL_KEYSTORE_PASSWORD
*/
public static final ConfigParam SSL_KEYSTORE_PASSWORD =
new ConfigParam(ReplicationSSLConfig.SSL_KEYSTORE_PASSWORD,
"", // default
false, // mutable
true); // forReplication
/**
* SSL KeyStore password source class
* @see ReplicationSSLConfig#SSL_KEYSTORE_PASSWORD_CLASS
*/
public static final ConfigParam SSL_KEYSTORE_PASSWORD_CLASS =
new ConfigParam(ReplicationSSLConfig.SSL_KEYSTORE_PASSWORD_CLASS,
"", // default
false, // mutable
true); // forReplication
/**
* SSL KeyStore password source constructor parameters
* @see ReplicationSSLConfig#SSL_KEYSTORE_PASSWORD_PARAMS
*/
public static final ConfigParam SSL_KEYSTORE_PASSWORD_PARAMS =
new ConfigParam(ReplicationSSLConfig.SSL_KEYSTORE_PASSWORD_PARAMS,
"", // default
false, // mutable
true); // forReplication
/**
* SSL KeyStore type
* @see ReplicationSSLConfig#SSL_KEYSTORE_TYPE
*/
public static final ConfigParam SSL_KEYSTORE_TYPE =
new ConfigParam(ReplicationSSLConfig.SSL_KEYSTORE_TYPE,
"", // default
false, // mutable
true); // forReplication
/**
* SSL server key alias
* @see ReplicationSSLConfig#SSL_SERVER_KEY_ALIAS
*/
public static final ConfigParam SSL_SERVER_KEY_ALIAS =
new ConfigParam(ReplicationSSLConfig.SSL_SERVER_KEY_ALIAS,
"", // default
false, // mutable
true); // forReplication
/**
* SSL client key alias
* @see ReplicationSSLConfig#SSL_CLIENT_KEY_ALIAS
*/
public static final ConfigParam SSL_CLIENT_KEY_ALIAS =
new ConfigParam(ReplicationSSLConfig.SSL_CLIENT_KEY_ALIAS,
"", // default
false, // mutable
true); // forReplication
/**
* SSL TrustStore file
* @see ReplicationSSLConfig#SSL_TRUSTSTORE_FILE
*/
public static final ConfigParam SSL_TRUSTSTORE_FILE =
new ConfigParam(ReplicationSSLConfig.SSL_TRUSTSTORE_FILE,
"", // default
false, // mutable
true); // forReplication
/**
* SSL TrustStore type
* @see ReplicationSSLConfig#SSL_TRUSTSTORE_TYPE
*/
public static final ConfigParam SSL_TRUSTSTORE_TYPE =
new ConfigParam(ReplicationSSLConfig.SSL_TRUSTSTORE_TYPE,
"", // default
false, // mutable
true); // forReplication
/**
* SSL cipher suites
* @see ReplicationSSLConfig#SSL_CIPHER_SUITES
*/
public static final ConfigParam SSL_CIPHER_SUITES =
new ConfigParam(ReplicationSSLConfig.SSL_CIPHER_SUITES,
"", // default
false, // mutable
true); // forReplication
/**
* SSL protocols
* @see ReplicationSSLConfig#SSL_PROTOCOLS
*/
public static final ConfigParam SSL_PROTOCOLS =
new ConfigParam(ReplicationSSLConfig.SSL_PROTOCOLS,
"", // default
false, // mutable
true); // forReplication
/**
* SSL Authenticator
* @see ReplicationSSLConfig#SSL_AUTHENTICATOR
*/
public static final ConfigParam SSL_AUTHENTICATOR =
new ConfigParam(ReplicationSSLConfig.SSL_AUTHENTICATOR,
"", // default
false, // mutable
true) { // forReplication
@Override
public void validateValue(String value) {
if (value == null) {
throw new IllegalArgumentException
("a value is required");
}
if (!SSLChannelFactory.isValidAuthenticator(value)) {
throw new IllegalArgumentException
(value + " a not a valid value");
}
}
};
/**
* SSL Authenticator class
* @see ReplicationSSLConfig#SSL_AUTHENTICATOR_CLASS
*/
public static final ConfigParam SSL_AUTHENTICATOR_CLASS =
new ConfigParam(ReplicationSSLConfig.SSL_AUTHENTICATOR_CLASS,
"", // default
false, // mutable
true); // forReplication
/**
* SSL Authenticator parameters
* @see ReplicationSSLConfig#SSL_AUTHENTICATOR_PARAMS
*/
public static final ConfigParam SSL_AUTHENTICATOR_PARAMS =
new ConfigParam(ReplicationSSLConfig.SSL_AUTHENTICATOR_PARAMS,
"", // default
false, // mutable
true); // forReplication
/**
* SSL Host Verifier
* @see ReplicationSSLConfig#SSL_HOST_VERIFIER
*/
public static final ConfigParam SSL_HOST_VERIFIER =
new ConfigParam(ReplicationSSLConfig.SSL_HOST_VERIFIER,
"", // default
false, // mutable
true) { // forReplication
@Override
public void validateValue(String value) {
if (value == null) {
throw new IllegalArgumentException
("a value is required");
}
if (!SSLChannelFactory.isValidHostVerifier(value)) {
throw new IllegalArgumentException
(value + " a not a valid value");
}
}
};
/**
* SSL Host Verifier class
* @see ReplicationSSLConfig#SSL_HOST_VERIFIER_CLASS
*/
public static final ConfigParam SSL_HOST_VERIFIER_CLASS =
new ConfigParam(ReplicationSSLConfig.SSL_HOST_VERIFIER_CLASS,
"", // default
false, // mutable
true); // forReplication
/**
* SSL Host Verifier parameters
* @see ReplicationSSLConfig#SSL_HOST_VERIFIER_PARAMS
*/
public static final ConfigParam SSL_HOST_VERIFIER_PARAMS =
new ConfigParam(ReplicationSSLConfig.SSL_HOST_VERIFIER_PARAMS,
"", // default
false, // mutable
true); // forReplication
/**
* Override the current JE version, for testing only.
*/
public static final ConfigParam TEST_JE_VERSION = new ConfigParam(
EnvironmentParams.REP_PARAM_PREFIX + "test.jeVersion",
"", // default
false, // mutable
true); // forReplication
/**
* @see ReplicationConfig#REPLAY_COST_PERCENT
*/
public static final IntConfigParam REPLAY_COST_PERCENT =
new IntConfigParam(ReplicationConfig.REPLAY_COST_PERCENT,
0, // min
200, // max
150, // default
false, // mutable
true); // forReplication
/**
* @see ReplicationConfig#REPLAY_FREE_DISK_PERCENT
*/
public static final IntConfigParam REPLAY_FREE_DISK_PERCENT =
new IntConfigParam(ReplicationConfig.REPLAY_FREE_DISK_PERCENT,
0, // min
99, // max
10, // default
false, // mutable
true); // forReplication
}