use of org.apache.zookeeper_voltpatches.ZooKeeper in project voltdb by VoltDB.
the class InvocationDispatcher method takeShutdownSaveSnapshot.
private final ClientResponseImpl takeShutdownSaveSnapshot(final StoredProcedureInvocation task, final InvocationClientHandler handler, final Connection ccxn, final AuthUser user, OverrideCheck bypass) {
// shutdown save snapshot is available for Pro edition only
if (!MiscUtils.isPro()) {
task.setParams();
return dispatch(task, handler, ccxn, user, bypass, false);
}
Object p0 = task.getParams().getParam(0);
final long zkTxnId;
if (p0 instanceof Long) {
zkTxnId = ((Long) p0).longValue();
} else if (p0 instanceof String) {
try {
zkTxnId = Long.parseLong((String) p0);
} catch (NumberFormatException e) {
return gracefulFailureResponse("Incorrect argument type", task.clientHandle);
}
} else {
return gracefulFailureResponse("Incorrect argument type", task.clientHandle);
}
VoltDBInterface voltdb = VoltDB.instance();
if (!voltdb.isPreparingShuttingdown()) {
log.warn("Ignoring shutdown save snapshot request as VoltDB is not shutting down");
return unexpectedFailureResponse("Ignoring shutdown save snapshot request as VoltDB is not shutting down", task.clientHandle);
}
final ZooKeeper zk = voltdb.getHostMessenger().getZK();
// network threads are blocked from making zookeeper calls
Future<Long> fut = voltdb.getSES(true).submit(new Callable<Long>() {
@Override
public Long call() {
try {
Stat stat = zk.exists(VoltZK.operationMode, false);
if (stat == null) {
VoltDB.crashLocalVoltDB("cluster operation mode zookeeper node does not exist");
return Long.MIN_VALUE;
}
return stat.getMzxid();
} catch (KeeperException | InterruptedException e) {
VoltDB.crashLocalVoltDB("Failed to stat the cluster operation zookeeper node", true, e);
return Long.MIN_VALUE;
}
}
});
try {
if (fut.get().longValue() != zkTxnId) {
return unexpectedFailureResponse("Internal error: cannot write a startup snapshot because the " + "current system state is not consistent with an orderly shutdown. " + "Please try \"voltadmin shutdown --save\" again.", task.clientHandle);
}
} catch (InterruptedException | ExecutionException e1) {
VoltDB.crashLocalVoltDB("Failed to stat the cluster operation zookeeper node", true, e1);
return null;
}
NodeSettings paths = m_catalogContext.get().getNodeSettings();
String data;
try {
data = new JSONStringer().object().keySymbolValuePair(SnapshotUtil.JSON_TERMINUS, zkTxnId).endObject().toString();
} catch (JSONException e) {
VoltDB.crashLocalVoltDB("Failed to create startup snapshot save command", true, e);
return null;
}
log.info("Saving startup snapshot");
consoleLog.info("Taking snapshot to save database contents");
final SimpleClientResponseAdapter alternateAdapter = new SimpleClientResponseAdapter(ClientInterface.SHUTDONW_SAVE_CID, "Blocking Startup Snapshot Save");
final InvocationClientHandler alternateHandler = new InvocationClientHandler() {
@Override
public boolean isAdmin() {
return handler.isAdmin();
}
@Override
public long connectionId() {
return ClientInterface.SHUTDONW_SAVE_CID;
}
};
final long sourceHandle = task.clientHandle;
task.setClientHandle(alternateAdapter.registerCallback(SimpleClientResponseAdapter.NULL_CALLBACK));
SnapshotUtil.SnapshotResponseHandler savCallback = new SnapshotUtil.SnapshotResponseHandler() {
@Override
public void handleResponse(ClientResponse r) {
if (r == null) {
String msg = "Snapshot save failed. The database is paused and the shutdown has been cancelled";
transmitResponseMessage(gracefulFailureResponse(msg, sourceHandle), ccxn, sourceHandle);
}
if (r.getStatus() != ClientResponse.SUCCESS) {
String msg = "Snapshot save failed: " + r.getStatusString() + ". The database is paused and the shutdown has been cancelled";
ClientResponseImpl resp = new ClientResponseImpl(ClientResponse.GRACEFUL_FAILURE, r.getResults(), msg, sourceHandle);
transmitResponseMessage(resp, ccxn, sourceHandle);
}
consoleLog.info("Snapshot taken successfully");
task.setParams();
dispatch(task, alternateHandler, alternateAdapter, user, bypass, false);
}
};
// network threads are blocked from making zookeeper calls
final byte[] guardContent = data.getBytes(StandardCharsets.UTF_8);
Future<Boolean> guardFuture = voltdb.getSES(true).submit(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
try {
ZKUtil.asyncMkdirs(zk, VoltZK.shutdown_save_guard, guardContent).get();
} catch (NodeExistsException itIsOk) {
return false;
} catch (InterruptedException | KeeperException e) {
VoltDB.crashLocalVoltDB("Failed to create shutdown save guard zookeeper node", true, e);
return false;
}
return true;
}
});
boolean created;
try {
created = guardFuture.get().booleanValue();
} catch (InterruptedException | ExecutionException e) {
VoltDB.crashLocalVoltDB("Failed to create shutdown save guard zookeeper node", true, e);
return null;
}
if (!created) {
return unexpectedFailureResponse("Internal error: detected concurrent invocations of \"voltadmin shutdown --save\"", task.clientHandle);
}
voltdb.getClientInterface().bindAdapter(alternateAdapter, null);
SnapshotUtil.requestSnapshot(sourceHandle, paths.resolve(paths.getSnapshoth()).toPath().toUri().toString(), SnapshotUtil.getShutdownSaveNonce(zkTxnId), true, SnapshotFormat.NATIVE, SnapshotPathType.SNAP_AUTO, data, savCallback, true);
return null;
}
use of org.apache.zookeeper_voltpatches.ZooKeeper in project voltdb by VoltDB.
the class VoltZK method updateClusterMetadata.
public static void updateClusterMetadata(Map<Integer, String> clusterMetadata) throws Exception {
ZooKeeper zk = VoltDB.instance().getHostMessenger().getZK();
List<String> metadataNodes = zk.getChildren(VoltZK.cluster_metadata, false);
Set<Integer> hostIds = new HashSet<Integer>();
for (String hostId : metadataNodes) {
hostIds.add(Integer.valueOf(hostId));
}
/*
* Remove anything that is no longer part of the cluster
*/
Set<Integer> keySetCopy = new HashSet<Integer>(clusterMetadata.keySet());
keySetCopy.removeAll(hostIds);
for (Integer failedHostId : keySetCopy) {
clusterMetadata.remove(failedHostId);
}
/*
* Add anything that is new
*/
Set<Integer> hostIdsCopy = new HashSet<Integer>(hostIds);
hostIdsCopy.removeAll(clusterMetadata.keySet());
List<Pair<Integer, ZKUtil.ByteArrayCallback>> callbacks = new ArrayList<Pair<Integer, ZKUtil.ByteArrayCallback>>();
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<Integer, ZKUtil.ByteArrayCallback> p : callbacks) {
Integer hostId = p.getFirst();
ZKUtil.ByteArrayCallback cb = p.getSecond();
try {
clusterMetadata.put(hostId, new String(cb.getData(), "UTF-8"));
} catch (KeeperException.NoNodeException e) {
}
}
}
use of org.apache.zookeeper_voltpatches.ZooKeeper in project voltdb by VoltDB.
the class UpdateSettings method run.
public VoltTable[] run(SystemProcedureExecutionContext ctx, byte[] settingsBytes) {
ZooKeeper zk = getHostMessenger().getZK();
Stat stat = null;
try {
stat = zk.exists(VoltZK.cluster_settings, false);
} catch (KeeperException | InterruptedException e) {
String msg = "Failed to stat cluster settings zookeeper node";
log.error(msg, e);
throw new VoltAbortException(msg);
}
final int version = stat.getVersion();
executeSysProcPlanFragments(createBarrierFragment(settingsBytes, version), DEP_updateSettingsBarrierAggregate);
return executeSysProcPlanFragments(createUpdateFragment(settingsBytes, version), DEP_updateSettingsAggregate);
}
use of org.apache.zookeeper_voltpatches.ZooKeeper in project voltdb by VoltDB.
the class UpdateSettings method executePlanFragment.
@Override
public DependencyPair executePlanFragment(Map<Integer, List<VoltTable>> dependencies, long fragmentId, ParameterSet params, SystemProcedureExecutionContext context) {
if (fragmentId == SysProcFragmentId.PF_updateSettingsBarrier) {
DependencyPair success = new DependencyPair.TableDependencyPair(DEP_updateSettingsBarrier, new VoltTable(new ColumnInfo[] { new ColumnInfo("UNUSED", VoltType.BIGINT) }));
if (log.isInfoEnabled()) {
log.info("Site " + CoreUtils.hsIdToString(m_site.getCorrespondingSiteId()) + " reached settings update barrier.");
}
return success;
} else if (fragmentId == SysProcFragmentId.PF_updateSettingsBarrierAggregate) {
Object[] paramarr = params.toArray();
byte[] settingsBytes = (byte[]) paramarr[0];
int version = ((Integer) paramarr[1]).intValue();
ZooKeeper zk = getHostMessenger().getZK();
Stat stat = null;
try {
stat = zk.setData(VoltZK.cluster_settings, settingsBytes, version);
} catch (KeeperException | InterruptedException e) {
String msg = "Failed to update cluster settings";
log.error(msg, e);
throw new SettingsException(msg, e);
}
log.info("Saved new cluster settings state");
return new DependencyPair.TableDependencyPair(DEP_updateSettingsBarrierAggregate, getVersionResponse(stat.getVersion()));
} else if (fragmentId == SysProcFragmentId.PF_updateSettings) {
Object[] paramarr = params.toArray();
byte[] settingsBytes = (byte[]) paramarr[0];
int version = ((Integer) paramarr[1]).intValue();
ClusterSettings settings = ClusterSettings.create(settingsBytes);
Pair<CatalogContext, CatalogSpecificPlanner> ctgdef = getVoltDB().settingsUpdate(settings, version);
context.updateSettings(ctgdef.getFirst(), ctgdef.getSecond());
VoltTable result = new VoltTable(VoltSystemProcedure.STATUS_SCHEMA);
result.addRow(VoltSystemProcedure.STATUS_OK);
return new DependencyPair.TableDependencyPair(DEP_updateSettings, result);
} else if (fragmentId == SysProcFragmentId.PF_updateSettingsAggregate) {
VoltTable result = VoltTableUtil.unionTables(dependencies.get(DEP_updateSettings));
return new DependencyPair.TableDependencyPair(DEP_updateSettingsAggregate, result);
} else {
VoltDB.crashLocalVoltDB("Received unrecognized plan fragment id " + fragmentId + " in UpdateSettings", false, null);
}
throw new RuntimeException("Should not reach this code");
}
use of org.apache.zookeeper_voltpatches.ZooKeeper in project voltdb by VoltDB.
the class MeshProber method considerMeshPlea.
@Override
public JoinAcceptor.PleaDecision considerMeshPlea(ZooKeeper zk, int hostId, JSONObject jo) {
checkArgument(zk != null, "zookeeper is null");
checkArgument(jo != null, "json object is null");
if (!HostCriteria.hasCriteria(jo)) {
return new JoinAcceptor.PleaDecision(String.format("Joining node version %s is incompatible with this node verion %s", jo.optString(SocketJoiner.VERSION_STRING, "(unknown)"), m_versionChecker.getVersionString()), false, false);
}
HostCriteria hc = new HostCriteria(jo);
Map<Integer, HostCriteria> hostCriteria = m_hostCriteria.get();
// when the cluster is forming anew)
if (!getNodeState().operational() && !hostCriteria.values().stream().anyMatch(c -> c.getNodeState().operational())) {
List<String> incompatibilities = asHostCriteria().listIncompatibilities(hc);
if (!incompatibilities.isEmpty()) {
Joiner joiner = Joiner.on("\n ").skipNulls();
String error = "Incompatible joining criteria:\n " + joiner.join(incompatibilities);
return new JoinAcceptor.PleaDecision(error, false, false);
}
return new JoinAcceptor.PleaDecision(null, true, false);
} else {
StartAction operationalStartAction = hostCriteria.values().stream().filter(c -> c.getNodeState().operational()).map(c -> c.getStartAction()).findFirst().orElse(getStartAction());
if (operationalStartAction == StartAction.PROBE && hc.getStartAction() != StartAction.PROBE) {
String msg = "Invalid VoltDB command. Please use init and start to join this cluster";
return new JoinAcceptor.PleaDecision(msg, false, false);
}
}
// how many hosts are already in the mesh?
Stat stat = new Stat();
try {
zk.getChildren(CoreZK.hosts, false, stat);
} catch (InterruptedException e) {
String msg = "Interrupted while considering mesh plea";
m_networkLog.error(msg, e);
return new JoinAcceptor.PleaDecision(msg, false, false);
} catch (KeeperException e) {
EnumSet<KeeperException.Code> closing = EnumSet.of(KeeperException.Code.SESSIONEXPIRED, KeeperException.Code.CONNECTIONLOSS);
if (closing.contains(e.code())) {
return new JoinAcceptor.PleaDecision("Shutting down", false, false);
} else {
String msg = "Failed to list hosts while considering a mesh plea";
m_networkLog.error(msg, e);
return new JoinAcceptor.PleaDecision(msg, false, false);
}
}
// connecting to already wholly formed cluster
if (stat.getNumChildren() >= getHostCount()) {
return new JoinAcceptor.PleaDecision(hc.isAddAllowed() ? null : "Cluster is already complete", hc.isAddAllowed(), false);
} else if (stat.getNumChildren() < getHostCount()) {
// check for concurrent rejoins
final int rejoiningHost = CoreZK.createRejoinNodeIndicator(zk, hostId);
if (rejoiningHost == -1) {
return new JoinAcceptor.PleaDecision(null, true, false);
} else {
String msg = "Only one host can rejoin at a time. Host " + rejoiningHost + " is still rejoining.";
return new JoinAcceptor.PleaDecision(msg, false, true);
}
}
return new JoinAcceptor.PleaDecision(null, true, false);
}
Aggregations