use of org.voltdb.settings.NodeSettings 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.voltdb.settings.NodeSettings in project voltdb by VoltDB.
the class InvocationDispatcher method getSnapshotCatalogFile.
private final File getSnapshotCatalogFile(JSONObject snapJo) throws JSONException {
NodeSettings paths = m_catalogContext.get().getNodeSettings();
String catFN = snapJo.getString(SnapshotUtil.JSON_NONCE) + ".jar";
SnapshotPathType pathType = SnapshotPathType.valueOf(snapJo.optString(SnapshotUtil.JSON_PATH_TYPE, SnapshotPathType.SNAP_PATH.name()));
switch(pathType) {
case SNAP_AUTO:
return new File(paths.resolve(paths.getSnapshoth()), catFN);
case SNAP_CL:
return new File(paths.resolve(paths.getCommandLogSnapshot()), catFN);
default:
File snapDH = new VoltFile(snapJo.getString(SnapshotUtil.JSON_PATH));
return new File(snapDH, catFN);
}
}
use of org.voltdb.settings.NodeSettings in project voltdb by VoltDB.
the class RealVoltDB method readPrimedDeployment.
ReadDeploymentResults readPrimedDeployment(Configuration config) {
/*
* Debate with the cluster what the deployment file should be
*/
try {
byte[] deploymentBytes = null;
try {
deploymentBytes = org.voltcore.utils.CoreUtils.urlToBytes(config.m_pathToDeployment);
} catch (Exception ex) {
//Let us get bytes from ZK
}
if (deploymentBytes == null) {
hostLog.error("Deployment information could not be obtained from cluster node or locally");
VoltDB.crashLocalVoltDB("No such deployment file: " + config.m_pathToDeployment, false, null);
}
DeploymentType deployment = CatalogUtil.getDeployment(new ByteArrayInputStream(deploymentBytes));
// wasn't a valid xml deployment file
if (deployment == null) {
hostLog.error("Not a valid XML deployment file at URL: " + config.m_pathToDeployment);
VoltDB.crashLocalVoltDB("Not a valid XML deployment file at URL: " + config.m_pathToDeployment, false, null);
return new ReadDeploymentResults(deploymentBytes, deployment);
}
// Override local sites count if possible
if (config.m_sitesperhost == VoltDB.UNDEFINED) {
config.m_sitesperhost = deployment.getCluster().getSitesperhost();
} else {
hostLog.info("Set the local sites count to " + config.m_sitesperhost);
consoleLog.info("CLI overrides the local sites count to " + config.m_sitesperhost);
}
NodeSettings nodeSettings = null;
// providers
switch(config.m_startAction) {
case GET:
// once a voltdbroot is inited, the path properties contain the true path values
Settings.initialize(config.m_voltdbRoot);
// only override the local sites count
nodeSettings = NodeSettings.create(config.asNodeSettingsMap());
break;
case PROBE:
// once a voltdbroot is inited, the path properties contain the true path values
Settings.initialize(config.m_voltdbRoot);
// only override the local sites count
nodeSettings = NodeSettings.create(config.asNodeSettingsMap());
File nodeSettingsFH = new File(getConfigDirectory(config), "path.properties");
consoleLog.info("Loaded node-specific settings from " + nodeSettingsFH.getPath());
hostLog.info("Loaded node-specific settings from " + nodeSettingsFH.getPath());
break;
case INITIALIZE:
Settings.initialize(config.m_voltdbRoot);
// voltdbroot value from config overrides voltdbroot value in the deployment
// file
nodeSettings = NodeSettings.create(config.asNodeSettingsMap(), config.asPathSettingsMap(), CatalogUtil.asNodeSettingsMap(deployment));
break;
default:
nodeSettings = NodeSettings.create(config.asNodeSettingsMap(), CatalogUtil.asNodeSettingsMap(deployment));
Settings.initialize(nodeSettings.getVoltDBRoot());
config.m_voltdbRoot = nodeSettings.getVoltDBRoot();
break;
}
m_nodeSettings = nodeSettings;
//Now its safe to save node settings
if (config.m_startAction != StartAction.GET) {
m_nodeSettings.store();
}
if (config.m_startAction == StartAction.PROBE) {
// once initialized the path properties contain the true path values
if (config.m_hostCount == VoltDB.UNDEFINED) {
config.m_hostCount = 1;
}
} else {
config.m_hostCount = deployment.getCluster().getHostcount();
}
/*
* Check for invalid deployment file settings (enterprise-only) in the community edition.
* Trick here is to print out all applicable problems and then stop, rather than stopping
* after the first one is found.
*/
if (!config.m_isEnterprise) {
boolean shutdownDeployment = false;
boolean shutdownAction = false;
// check license features for community version
if ((deployment.getCluster() != null) && (deployment.getCluster().getKfactor() > 0)) {
consoleLog.error("K-Safety is not supported " + "in the community edition of VoltDB.");
shutdownDeployment = true;
}
if ((deployment.getSnapshot() != null) && (deployment.getSnapshot().isEnabled())) {
consoleLog.error("Snapshots are not supported " + "in the community edition of VoltDB.");
shutdownDeployment = true;
}
if ((deployment.getCommandlog() != null) && (deployment.getCommandlog().isEnabled())) {
consoleLog.error("Command logging is not supported " + "in the community edition of VoltDB.");
shutdownDeployment = true;
}
if ((deployment.getExport() != null) && deployment.getExport().getConfiguration() != null && !deployment.getExport().getConfiguration().isEmpty()) {
consoleLog.error("Export is not supported " + "in the community edition of VoltDB.");
shutdownDeployment = true;
}
// check the start action for the community edition
if (m_config.m_startAction != StartAction.CREATE) {
consoleLog.error("Start action \"" + m_config.m_startAction.getClass().getSimpleName() + "\" is not supported in the community edition of VoltDB.");
shutdownAction = true;
}
// if the process needs to stop, try to be helpful
if (shutdownAction || shutdownDeployment) {
String msg = "This process will exit. Please run VoltDB with ";
if (shutdownDeployment) {
msg += "a deployment file compatible with the community edition";
}
if (shutdownDeployment && shutdownAction) {
msg += " and ";
}
if (shutdownAction && !shutdownDeployment) {
msg += "the CREATE start action";
}
msg += ".";
VoltDB.crashLocalVoltDB(msg, false, null);
}
}
return new ReadDeploymentResults(deploymentBytes, deployment);
} catch (Exception e) {
/*
* When a settings exception is caught (e.g. reading a broken properties file),
* we probably just want to crash the DB anyway
*/
consoleLog.fatal(e.getMessage());
VoltDB.crashLocalVoltDB(e.getMessage());
return null;
}
}
Aggregations