Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/* This file is part of VoltDB.
* Copyright (C) 2008-2020 VoltDB Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with VoltDB. If not, see .
*/
package org.voltdb;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.apache.zookeeper_voltpatches.CreateMode;
import org.apache.zookeeper_voltpatches.KeeperException;
import org.apache.zookeeper_voltpatches.ZooDefs.Ids;
import org.apache.zookeeper_voltpatches.ZooKeeper;
import org.json_voltpatches.JSONException;
import org.json_voltpatches.JSONObject;
import org.voltcore.logging.VoltLogger;
import org.voltcore.utils.CoreUtils;
import org.voltcore.utils.Pair;
import org.voltcore.zk.CoreZK;
import org.voltcore.zk.ZKUtil;
import org.voltcore.zk.ZooKeeperLock;
import org.voltdb.iv2.LeaderCache;
import org.voltdb.iv2.LeaderCache.LeaderCallBackInfo;
import org.voltdb.iv2.MigratePartitionLeaderInfo;
import com.google_voltpatches.common.base.Charsets;
import com.google_voltpatches.common.collect.Sets;
/**
* VoltZK provides constants for all voltdb-registered
* ZooKeeper paths.
*/
public class VoltZK {
static final VoltLogger tmLog = new VoltLogger("TM");
private final static String ERROR_DECOMMISSION = "while decommissioning replicas is in progress";
private final static String ERROR_REDUCEDCLUSTERSAFETY = "while cluster is in reduced safety mode";
private final static String ERROR_REJOIN = "while node rejoin is in progress";
private final static String ERROR_LEADER_MIGRATION = "while leader migration is in progress";
private final static String ERROR_CATALOG_UPDATE = "while catalog update is in progress";
private final static String ERROR_ELASTIC_OPERATION = "while elastic operation is in progress";
private final static String ERROR_MP_REPAIR = "while leader promotion or transaction repair are in progress";
private final static String ERROR_LICENSE_UPDATE = "while live license update is in progress";
public static final String root = "/db";
public static final String buildstring = "/db/buildstring";
public static final String catalogbytes = "/db/catalogbytes";
public static final String license = "/db/license";
//This node doesn't mean as much as it used to, it is accurate at startup
//but isn't updated after elastic operation. We use the cartographer for most things
//now
public static final String topology = "/db/topology";
public static final String replicationconfig = "/db/replicationconfig";
public static final String rejoinLock = "/db/rejoin_lock";
public static final String perPartitionTxnIds = "/db/perPartitionTxnIds";
public static final String operationMode = "/db/operation_mode";
public static final String exportGenerations = "/db/export_generations";
public static final String exportCoordination = "/db/export_coordination";
// configuration (ports, interfaces, ...)
public static final String cluster_metadata = "/db/cluster_metadata";
// localMetadata json property names
public static final String drPublicHostProp = "drPublicHost";
public static final String drPublicPortProp = "drPublicPort";
/*
* mailboxes
*
* Contents in the mailbox ZK nodes are all simple JSON objects. No nested
* objects should be stored in them. They must all have a field called
* "HSId" that maps to their host-site ID. Some of them may also contain a
* "partitionId" field.
*/
public static enum MailboxType {
ClientInterface, ExecutionSite, Initiator, StatsAgent,
OTHER
}
public static final String nt_mailboxes = "/db/cl_mailboxes";
// snapshot and command log
public static final String completed_snapshots = "/db/completed_snapshots";
public static final String nodes_currently_snapshotting = "/db/nodes_currently_snapshotting";
public static final String restore = "/db/restore";
public static final String restore_barrier = "/db/restore_barrier";
public static final String restore_barrier2 = "/db/restore_barrier2";
public static final String restore_snapshot_id = "/db/restore/snapshot_id";
public static final String request_truncation_snapshot = "/db/request_truncation_snapshot";
public static final String snapshot_truncation_master = "/db/snapshot_truncation_master";
public static final String test_scan_path = "/db/test_scan_path"; // (test only)
public static final String user_snapshot_request = "/db/user_snapshot_request";
public static final String user_snapshot_response = "/db/user_snapshot_response";
public static final String commandlog_init_barrier = "/db/commmandlog_init_barrier";
// leader election
// root for MigratePartitionLeader information nodes
public static final String migrate_partition_leader_info = "/core/migrate_partition_leader_info";
public static final String drConsumerPartitionMigration = "/db/dr_consumer_partition_migration";
public static final String iv2masters = "/db/iv2masters";
public static final String iv2appointees = "/db/iv2appointees";
public static final String iv2mpi = "/db/iv2mpi";
public static final String leaders = "/db/leaders";
public static final String leaders_initiators = "/db/leaders/initiators";
public static final String leaders_globalservice = "/db/leaders/globalservice";
public static final String lastKnownLiveNodes = "/db/lastKnownLiveNodes";
public static final String debugLeadersInfo(ZooKeeper zk) {
StringBuilder builder = new StringBuilder("ZooKeeper:\n");
printZKDir(zk, iv2masters, builder);
printZKDir(zk, iv2appointees, builder);
printZKDir(zk, iv2mpi, builder);
printZKDir(zk, leaders_initiators, builder);
printZKDir(zk, leaders_globalservice, builder);
return builder.toString();
}
public static final void printZKDir(ZooKeeper zk, String dir, StringBuilder builder) {
builder.append(dir).append(":\t ");
try {
List keys = zk.getChildren(dir, null);
boolean isData = false;
for (String key: keys) {
String path = ZKUtil.joinZKPath(dir, key);
byte[] arr = zk.getData(path, null, null);
if (arr != null) {
String data = new String(arr, "UTF-8");
if (iv2masters.equals(dir) || iv2appointees.equals(dir)) {
LeaderCallBackInfo info = LeaderCache.buildLeaderCallbackFromString(data);
data = info.toString();
}
isData = true;
builder.append(key).append(" -> ").append(data).append(",");
} else {
// path may be a dir instead
List children = zk.getChildren(path, null);
if (children != null) {
builder.append("\n");
printZKDir(zk, path, builder);
}
}
}
if (isData) {
builder.append("\n");
}
} catch (KeeperException | InterruptedException | UnsupportedEncodingException e) {
builder.append(e.getMessage());
}
}
// flag of initialization process complete
public static final String init_completed = "/db/init_completed";
// start action of node in the current system (ephemeral)
public static final String start_action = "/db/start_action";
public static final String start_action_node = ZKUtil.joinZKPath(start_action, "node_");
/*
* Processes that want to be mutually exclusive create children here
*/
public static final String actionBlockers = "/db/action_blockers";
// being able to use as constant string
public static final String migrate_partition_leader = "migrate_partition_leader_blocker";
public static final String migratePartitionLeaderBlocker = actionBlockers + "/" + migrate_partition_leader;
// three elastic blockers
// elasticOperationInProgress blocks the rejoin (create in init state, release before data migration start)
// banElasticOperation blocks elastic operation (currently created by DRProducer if the agreed protocol version
// for the mesh does not support elastic operation during DR (i.e. version <= 7).
// It is now only released after a DR global reset.)
// elasticMigration only blocks SPI Migration
private static final String leafNodeElasticOperationInProgress = "elastic_blocker";
public static final String elasticOperationInProgress = actionBlockers + "/" + leafNodeElasticOperationInProgress;
private static final String leafNodeBanElasticOperation = "no_elastic_blocker";
public static final String banElasticOperation = actionBlockers + "/" + leafNodeBanElasticOperation;
private static final String leafNodeElasticMigration = "elastic_migration_blocker";
public static final String elasticMigration = actionBlockers + "/" + leafNodeElasticMigration;
private static final String leafNodeRejoinInProgress = "rejoin_blocker";
public static final String rejoinInProgress = actionBlockers + "/" + leafNodeRejoinInProgress;
private static final String leafNodeCatalogUpdateInProgress = "uac_nt_blocker";
public static final String catalogUpdateInProgress = actionBlockers + "/" + leafNodeCatalogUpdateInProgress;
private static final String leafNodeLicenseUpdateInProgress = "license_update_blocker";
public static final String licenseUpdateInProgress = actionBlockers + "/" + leafNodeLicenseUpdateInProgress;
//register partition while the partition elects a new leader upon node failure
private static final String mpRepairBlocker = "mp_repair_blocker";
public static final String mpRepairInProgress = actionBlockers + "/" + mpRepairBlocker;
private static final String decommissionReplicas = "decommissionReplicas_blocker";
public static final String decommissionReplicasInProgress = actionBlockers + "/" + decommissionReplicas;
// ReducedClusterSafety has longer scope than decommissionReplicasBlocker (will not been release until transfer back to full cluster mode)
// It prohibit cluster topology changed related operation
// but do allow snapshot operation
private static final String leafReducedClusterSafety = "reduced_clustersafety_block";
public static final String reducedClusterSafety = actionBlockers + "/" + leafReducedClusterSafety;
private static final String snapshotBlocker = "snapshot_blocker";
public static final String snapshotSetupInProgress = actionBlockers + "/" + snapshotBlocker;
public static final String request_truncation_snapshot_node = ZKUtil.joinZKPath(request_truncation_snapshot, "request_");
// Synchronized State Machine
public static final String syncStateMachine = "/db/synchronized_states";
// Settings base
public static final String settings_base = "/db/settings";
// Cluster settings
public static final String cluster_settings = ZKUtil.joinZKPath(settings_base, "cluster");
// Shutdown save snapshot guard
public static final String shutdown_save_guard = "/db/shutdown_save_guard";
// Host ids that be stopped by calling @StopNode
public static final String host_ids_be_stopped = "/db/host_ids_be_stopped";
public static final String actionLock = "/db/action_lock";
public static final String hashMismatchedReplicas = "/db/mismatched";
// Persistent nodes (mostly directories) to create on startup
public static final String[] ZK_HIERARCHY = {
root,
cluster_metadata,
drConsumerPartitionMigration,
operationMode,
iv2masters,
iv2appointees,
iv2mpi,
leaders,
leaders_initiators,
leaders_globalservice,
lastKnownLiveNodes,
syncStateMachine,
settings_base,
cluster_settings,
actionBlockers,
request_truncation_snapshot,
host_ids_be_stopped,
actionLock,
hashMismatchedReplicas,
catalogbytes,
nt_mailboxes
};
/**
* Race to create the persistent nodes.
*/
public static void createPersistentZKNodes(ZooKeeper zk) {
LinkedList callbacks = new LinkedList();
for (int i=0; i < VoltZK.ZK_HIERARCHY.length; i++) {
ZKUtil.StringCallback cb = new ZKUtil.StringCallback();
callbacks.add(cb);
zk.create(VoltZK.ZK_HIERARCHY[i], null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT, cb, null);
}
for (ZKUtil.StringCallback cb : callbacks) {
try {
cb.get();
} catch (org.apache.zookeeper_voltpatches.KeeperException.NodeExistsException e) {
// this is an expected race.
} catch (Exception e) {
VoltDB.crashLocalVoltDB(e.getMessage(), true, e);
}
}
}
/**
* Helper method for parsing mailbox node contents into Java objects.
* @throws JSONException
*/
public static List parseMailboxContents(List jsons) throws JSONException {
ArrayList objects = new ArrayList(jsons.size());
for (String json : jsons) {
MailboxNodeContent content = null;
JSONObject jsObj = new JSONObject(json);
long HSId = jsObj.getLong("HSId");
Integer partitionId = null;
if (jsObj.has("partitionId")) {
partitionId = jsObj.getInt("partitionId");
}
content = new MailboxNodeContent(HSId, partitionId);
objects.add(content);
}
return objects;
}
public static void updateClusterMetadata(Map clusterMetadata) throws Exception {
ZooKeeper zk = VoltDB.instance().getHostMessenger().getZK();
List metadataNodes = zk.getChildren(VoltZK.cluster_metadata, false);
Set hostIds = new HashSet();
for (String hostId : metadataNodes) {
hostIds.add(Integer.valueOf(hostId));
}
/*
* Remove anything that is no longer part of the cluster
*/
Set keySetCopy = new HashSet(clusterMetadata.keySet());
keySetCopy.removeAll(hostIds);
for (Integer failedHostId : keySetCopy) {
clusterMetadata.remove(failedHostId);
}
/*
* Add anything that is new
*/
Set hostIdsCopy = new HashSet(hostIds);
hostIdsCopy.removeAll(clusterMetadata.keySet());
List> callbacks =
new ArrayList>();
for (Integer hostId : hostIdsCopy) {
ZKUtil.ByteArrayCallback cb = new ZKUtil.ByteArrayCallback();
callbacks.add(Pair.of(hostId, cb));
zk.getData(VoltZK.cluster_metadata + "/" + hostId, false, cb, null);
}
for (Pair p : callbacks) {
Integer hostId = p.getFirst();
ZKUtil.ByteArrayCallback cb = p.getSecond();
try {
clusterMetadata.put( hostId, new String(cb.get(), "UTF-8"));
} catch (KeeperException.NoNodeException e){}
}
}
public static Pair getDRPublicInterfaceAndPortFromMetadata(String metadata)
throws IllegalArgumentException {
try {
JSONObject obj = new JSONObject(metadata);
// Precedence order for host:port on which consumers should connect:
// - drPublic
// - drInterface
// - 0th element in interfaces
String hostName = obj.getString(drPublicHostProp);
if (hostName == null || hostName.isEmpty()) {
hostName = obj.getString("drInterface");
}
if (hostName == null || hostName.length() <= 0) {
hostName = obj.getJSONArray("interfaces").getString(0);
}
assert(hostName != null);
assert(hostName.length() > 0);
int port = obj.getInt(drPublicPortProp);
if (port == VoltDB.DISABLED_PORT) {
port = obj.getInt("drPort");
}
return Pair.of(hostName, port);
} catch (JSONException e) {
throw new IllegalArgumentException("Error parsing host metadata", e);
}
}
/**
* Convert a list of ZK nodes named HSID_SUFFIX (such as that used by LeaderElector)
* into a list of HSIDs.
*/
public static List childrenToReplicaHSIds(Collection children)
{
List replicas = new ArrayList(children.size());
for (String child : children) {
long HSId = Long.parseLong(CoreZK.getPrefixFromChildName(child));
replicas.add(HSId);
}
return replicas;
}
public static void createStartActionNode(ZooKeeper zk, final int hostId, StartAction action) {
byte [] startActionBytes = null;
try {
startActionBytes = action.toString().getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
VoltDB.crashLocalVoltDB("Utf-8 encoding is not supported in current platform", false, e);
}
zk.create(VoltZK.start_action_node + hostId, startActionBytes, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL,
new ZKUtil.StringCallback(), null);
}
public static int getHostIDFromChildName(String childName) {
return Integer.parseInt(childName.split("_")[1]);
}
/**
* @param zk
* @param node
* @return true when @param zk @param node exists, false otherwise
*/
public static boolean zkNodeExists(ZooKeeper zk, String node)
{
try {
if (zk.exists(node, false) == null) {
return false;
}
} catch (KeeperException | InterruptedException e) {
VoltDB.crashLocalVoltDB("Unable to check ZK node exists: " + node, true, e);
}
return true;
}
/**
* Create a ZK node under action blocker directory. Exclusive execution of elastic operation, rejoin or catalog
* update is checked.
*
* Catalog update can not happen during node rejoin.
*
* Node rejoin can not happen during catalog update or elastic operation.
*
* Elastic operation can not happen during node rejoin or catalog update.
*
* @param zk
* @param node
* @param hostLog
* @param request
* @return null for success, non-null for error string
*/
public static String createActionBlocker(ZooKeeper zk, String node, CreateMode mode, VoltLogger hostLog, String request) {
//Acquire a lock before creating a blocker and validate actions.
ZooKeeperLock zklock = new ZooKeeperLock(zk, VoltZK.actionLock, "lock");
String lockingMessage = null;
try {
if(!zklock.acquireLockWithTimeout(TimeUnit.SECONDS.toMillis(60))) {
lockingMessage = "Could not acquire a lock to create action blocker:" + request;
} else {
lockingMessage = setActionBlocker(zk, node, mode, hostLog, request);
}
} finally {
try {
zklock.releaseLock();
} catch (IOException e) {}
}
return lockingMessage;
}
private static String setActionBlocker(ZooKeeper zk, String node, CreateMode mode, VoltLogger hostLog, String request) {
try {
zk.create(node,
null,
Ids.OPEN_ACL_UNSAFE,
mode);
} catch (KeeperException e) {
if (e.code() != KeeperException.Code.NODEEXISTS) {
VoltDB.crashLocalVoltDB("Unable to create action blocker " + node, true, e);
}
// node exists
return "Invalid " + request + " request: Can't do " + request +
" while another one is in progress. Please retry " + request + " later.";
} catch (InterruptedException e) {
VoltDB.crashLocalVoltDB("Unable to create action blocker " + node, true, e);
}
// Validate exclusive access of elastic operation, rejoin, MigratePartitionLeader and catalog update.
String errorMsg = null;
try {
List blockers = zk.getChildren(VoltZK.actionBlockers, false);
switch (node) {
case catalogUpdateInProgress:
if (blockers.contains(leafNodeRejoinInProgress)) {
errorMsg = ERROR_REJOIN;
} else if (blockers.contains(mpRepairBlocker)){
// Avoid UAC during MP repair or promotion since UAC will invoke GlobalServiceElector to
// register other promotable services while MPI is accepting promotion
errorMsg = ERROR_MP_REPAIR;
} else if (blockers.contains(leafNodeElasticOperationInProgress)) {
errorMsg = ERROR_ELASTIC_OPERATION;
}
break;
case rejoinInProgress:
// node rejoin can not happen during UAC or elastic operation
if (blockers.contains(leafNodeCatalogUpdateInProgress)) {
errorMsg = ERROR_CATALOG_UPDATE;
} else if (blockers.contains(leafNodeElasticOperationInProgress)) {
errorMsg = ERROR_ELASTIC_OPERATION;
} else if (blockers.contains(migrate_partition_leader)){
errorMsg = ERROR_LEADER_MIGRATION;
} else if (blockers.contains(mpRepairBlocker)){
// Upon node failures, a MP repair blocker may be registered right before they
// unregistered after repair is done. Let rejoining nodes wait to avoid any
// interference with the transaction repair process.
errorMsg = ERROR_MP_REPAIR;
} else if (blockers.contains(decommissionReplicas)){
errorMsg = ERROR_DECOMMISSION;
} else if (blockers.contains(leafReducedClusterSafety)){
errorMsg = ERROR_REDUCEDCLUSTERSAFETY;
} else if (blockers.contains(leafNodeLicenseUpdateInProgress)) {
errorMsg = ERROR_LICENSE_UPDATE;
}
break;
case elasticOperationInProgress:
// elastic operation can not happen during node rejoin
if (blockers.contains(leafNodeRejoinInProgress)) {
errorMsg = ERROR_REJOIN;
} else if (blockers.contains(leafNodeCatalogUpdateInProgress)) {
errorMsg = ERROR_CATALOG_UPDATE;
} else if (blockers.contains(leafNodeBanElasticOperation)) {
errorMsg = "while elastic operation is blocked by DR established with a cluster that "
+ "does not support remote elastic operation during DR. "
+ "DR needs to be reset before elastic operation is allowed again.";
} else if ( blockers.contains(migrate_partition_leader)) {
errorMsg = ERROR_LEADER_MIGRATION;
} else if (blockers.contains(decommissionReplicas)){
errorMsg = ERROR_DECOMMISSION;
} else if (blockers.contains(leafReducedClusterSafety)){
errorMsg = ERROR_REDUCEDCLUSTERSAFETY;
}
break;
case migratePartitionLeaderBlocker:
//MigratePartitionLeader can not happen when join (before data fully migrated), rejoin, catalog update, or repair is in progress.
blockers.remove(leafNodeBanElasticOperation);
if (blockers.size() > 1) {
errorMsg = ERROR_ELASTIC_OPERATION;
} else if (blockers.contains(decommissionReplicas)){
errorMsg = ERROR_DECOMMISSION;
} else if (blockers.contains(leafReducedClusterSafety)){
errorMsg = ERROR_REDUCEDCLUSTERSAFETY;
}
break;
case elasticMigration:
// elastic operation balancePartition currently cannot coexist with partition leader migration
if (blockers.contains(migrate_partition_leader)) {
errorMsg = ERROR_LEADER_MIGRATION;
}
break;
case banElasticOperation:
if (blockers.contains(leafNodeElasticOperationInProgress)) {
errorMsg = ERROR_ELASTIC_OPERATION;
}
break;
case mpRepairInProgress:
break;
case decommissionReplicasInProgress:
if (blockers.contains(snapshotBlocker)) {
errorMsg = "while snapshot is in progress";
}
break;
case reducedClusterSafety:
break;
case snapshotSetupInProgress:
if (blockers.contains(decommissionReplicas)) {
errorMsg = ERROR_DECOMMISSION;
}
break;
case licenseUpdateInProgress:
if (blockers.contains(leafNodeRejoinInProgress)) {
errorMsg = ERROR_REJOIN;
}
break;
default:
// not possible
VoltDB.crashLocalVoltDB("Invalid request " + node , true, new RuntimeException("Non-supported " + request));
}
} catch (Exception e) {
// should not be here
VoltDB.crashLocalVoltDB("Error reading children of ZK " + VoltZK.actionBlockers + ": " + e.getMessage(), true, e);
}
if (errorMsg != null) {
VoltZK.removeActionBlocker(zk, node, hostLog);
return "Can't do " + request + " " + errorMsg;
}
hostLog.info("Create action blocker " + node + " successfully.");
// successfully create a ZK node
return null;
}
public static boolean removeActionBlocker(ZooKeeper zk, String node, VoltLogger log) {
if (log != null) {
log.info("Removing action blocker " + node);
}
try {
zk.delete(node, -1);
} catch (KeeperException e) {
if (e.code() == KeeperException.Code.NONODE) {
if (log != null) {
log.info("Action blocker " + node + " does not exist.");
}
return true;
}
if (log != null) {
log.error("Failed to remove action blocker: " + node + "\n" + e.getMessage(), e);
}
return false;
} catch (InterruptedException e) {
if (log != null) {
log.error("Failed to remove action blocker: " + node + "\n" + e.getMessage(), e);
}
return false;
}
if (log != null) {
log.info("Remove action blocker " + node + " successfully.");
}
return true;
}
public static void removeStopNodeIndicator(ZooKeeper zk, String node, VoltLogger log) {
try {
ZKUtil.deleteRecursively(zk, node);
} catch (KeeperException e) {
if (e.code() != KeeperException.Code.NONODE) {
log.debug("Failed to remove stop node indicator " + node + " on ZK: " + e.getMessage());
}
return;
} catch (InterruptedException ignore) {}
}
/**
* Save MigratePartitionLeader information for error handling
*/
public static boolean createMigratePartitionLeaderInfo(ZooKeeper zk, MigratePartitionLeaderInfo info) {
try {
zk.create(migrate_partition_leader_info, info.toBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
} catch (KeeperException e) {
if (e.code() == KeeperException.Code.NODEEXISTS) {
try {
zk.setData(migrate_partition_leader_info, info.toBytes(), -1);
} catch (KeeperException | InterruptedException | JSONException e1) {
}
return false;
}
org.voltdb.VoltDB.crashLocalVoltDB("Unable to create MigratePartitionLeader Indicator", true, e);
} catch (InterruptedException | JSONException e) {
org.voltdb.VoltDB.crashLocalVoltDB("Unable to create MigratePartitionLeader Indicator", true, e);
}
return true;
}
/**
* get MigratePartitionLeader information
*/
public static MigratePartitionLeaderInfo getMigratePartitionLeaderInfo(ZooKeeper zk) {
try {
byte[] data = zk.getData(migrate_partition_leader_info, null, null);
if (data != null) {
MigratePartitionLeaderInfo info = new MigratePartitionLeaderInfo(data);
return info;
}
} catch (KeeperException | InterruptedException | JSONException e) {
}
return null;
}
/**
* Removes the MigratePartitionLeader info
*/
public static void removeMigratePartitionLeaderInfo(ZooKeeper zk) {
try {
zk.delete(migrate_partition_leader_info, -1);
} catch (KeeperException | InterruptedException e) {
}
}
/**
* @param zk ZooKeeper
* @return true if any hosts work on snapshot
*/
public static boolean hasHostsSnapshotting(ZooKeeper zk) {
try {
List nodesSnapshotting = zk.getChildren(VoltZK.nodes_currently_snapshotting, false);
return (!nodesSnapshotting.isEmpty());
} catch (KeeperException | InterruptedException e) {
VoltDB.crashLocalVoltDB("Unable to read snapshotting hosts.", true, e);
}
return false;
}
/**
* Store hash mismatched replicas
*/
public static void addHashMismatchedSite(ZooKeeper zk, long hsId) {
try {
int hostId = CoreUtils.getHostIdFromHSId(hsId);
// With 10000x - site id, no sites would have the same idPath in reality.
String idPath = String.valueOf(hostId * 10000) + CoreUtils.getSiteIdFromHSId(hsId);
String id = Long.toString(Long.MAX_VALUE) + "/" + Long.toString(hsId);
zk.create(ZKUtil.joinZKPath(hashMismatchedReplicas, idPath),
id.getBytes(Charsets.UTF_8),
Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
} catch (KeeperException.NodeExistsException e) {
} catch (Exception e) {
VoltDB.crashLocalVoltDB("Unable to store hash mismatched replica info", true, e);
}
}
public static void removeHashMismatchedSite(ZooKeeper zk, long hsId) {
try {
int hostId = CoreUtils.getHostIdFromHSId(hsId);
String idPath = String.valueOf(hostId * 10000) + CoreUtils.getSiteIdFromHSId(hsId);
final String path = ZKUtil.joinZKPath(hashMismatchedReplicas, idPath);
zk.delete(path, -1);
} catch (KeeperException.NoNodeException e) {
} catch (Exception e) {
VoltDB.crashLocalVoltDB("Unable to delete hash mismatched replica info", true, e);
}
}
public static boolean hasHashMismatchedSite(ZooKeeper zk) {
try {
List mismatchedReplicas = zk.getChildren(hashMismatchedReplicas, false);
return (!mismatchedReplicas.isEmpty());
} catch (KeeperException | InterruptedException e) {
VoltDB.crashLocalVoltDB("Unable to read hash mismatched sites.", true, e);
}
return false;
}
public static void registerMailBoxForNT(ZooKeeper zk, long hsid) {
String path = ZKUtil.joinZKPath(nt_mailboxes, Long.toString(hsid));
try {
zk.create(path, null, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
} catch (KeeperException.NoNodeException e) {
} catch (Exception e) {
VoltDB.crashLocalVoltDB("Unable to add client interface mailbox", true, e);
}
}
public static Set getMailBoxesForNT(ZooKeeper zk) {
Set mailboxes = Sets.newHashSet();
try {
List clMailboxes = zk.getChildren(nt_mailboxes, false);
mailboxes = clMailboxes.stream().map(Long::valueOf).collect(Collectors.toSet());
} catch (KeeperException | InterruptedException e) {
VoltDB.crashLocalVoltDB("Unable to read client interface mailboxes.", true, e);
}
return mailboxes;
}
}