use of org.apache.zookeeper_voltpatches.ZooKeeper in project voltdb by VoltDB.
the class ZKUtil method getClient.
public static final ZooKeeper getClient(String zkAddress, int timeout, Set<Long> verbotenThreads) throws Exception {
final Semaphore zkConnect = new Semaphore(0);
ZooKeeper zk = new ZooKeeper(zkAddress, 2000, new Watcher() {
@Override
public void process(WatchedEvent event) {
if (event.getState() == KeeperState.SyncConnected) {
zkConnect.release();
}
}
}, verbotenThreads);
if (!zkConnect.tryAcquire(timeout, TimeUnit.MILLISECONDS)) {
return null;
}
return zk;
}
use of org.apache.zookeeper_voltpatches.ZooKeeper in project voltdb by VoltDB.
the class RealVoltDB method readDeploymentAndCreateStarterCatalogContext.
boolean readDeploymentAndCreateStarterCatalogContext(VoltDB.Configuration config) {
/*
* Debate with the cluster what the deployment file should be
*/
try {
ZooKeeper zk = m_messenger.getZK();
byte[] deploymentBytes = null;
try {
deploymentBytes = org.voltcore.utils.CoreUtils.urlToBytes(m_config.m_pathToDeployment);
} catch (Exception ex) {
//Let us get bytes from ZK
}
DeploymentType deployment = null;
try {
if (deploymentBytes != null) {
CatalogUtil.writeCatalogToZK(zk, // Fill in innocuous values for non-deployment stuff
0, 0L, 0L, // spin loop in Inits.LoadCatalog.run() needs
new byte[] {}, // this to be of zero length until we have a real catalog.
null, deploymentBytes);
hostLog.info("URL of deployment: " + m_config.m_pathToDeployment);
} else {
CatalogAndIds catalogStuff = CatalogUtil.getCatalogFromZK(zk);
deploymentBytes = catalogStuff.deploymentBytes;
}
} catch (KeeperException.NodeExistsException e) {
CatalogAndIds catalogStuff = CatalogUtil.getCatalogFromZK(zk);
byte[] deploymentBytesTemp = catalogStuff.deploymentBytes;
if (deploymentBytesTemp != null) {
//We will ignore the supplied or default deployment anyways.
if (deploymentBytes != null && !m_config.m_deploymentDefault) {
byte[] deploymentHashHere = CatalogUtil.makeDeploymentHash(deploymentBytes);
if (!(Arrays.equals(deploymentHashHere, catalogStuff.getDeploymentHash()))) {
hostLog.warn("The locally provided deployment configuration did not " + " match the configuration information found in the cluster.");
} else {
hostLog.info("Deployment configuration pulled from other cluster node.");
}
}
//Use remote deployment obtained.
deploymentBytes = deploymentBytesTemp;
} else {
hostLog.error("Deployment file could not be loaded locally or remotely, " + "local supplied path: " + m_config.m_pathToDeployment);
deploymentBytes = null;
}
} catch (KeeperException.NoNodeException e) {
// no deploymentBytes case is handled below. So just log this error.
if (hostLog.isDebugEnabled()) {
hostLog.debug("Error trying to get deployment bytes from cluster", e);
}
}
if (deploymentBytes == null) {
hostLog.error("Deployment information could not be obtained from cluster node or locally");
VoltDB.crashLocalVoltDB("No such deployment file: " + m_config.m_pathToDeployment, false, null);
}
if (deployment == null) {
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: " + m_config.m_pathToDeployment);
VoltDB.crashLocalVoltDB("Not a valid XML deployment file at URL: " + m_config.m_pathToDeployment, false, null);
}
/*
* 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 (!m_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);
}
}
// note the heart beats are specified in seconds in xml, but ms internally
HeartbeatType hbt = deployment.getHeartbeat();
if (hbt != null) {
m_config.m_deadHostTimeoutMS = hbt.getTimeout() * 1000;
m_messenger.setDeadHostTimeout(m_config.m_deadHostTimeoutMS);
} else {
hostLog.info("Dead host timeout set to " + m_config.m_deadHostTimeoutMS + " milliseconds");
}
PartitionDetectionType pt = deployment.getPartitionDetection();
if (pt != null) {
m_config.m_partitionDetectionEnabled = pt.isEnabled();
m_messenger.setPartitionDetectionEnabled(m_config.m_partitionDetectionEnabled);
}
// get any consistency settings into config
ConsistencyType consistencyType = deployment.getConsistency();
if (consistencyType != null) {
m_config.m_consistencyReadLevel = Consistency.ReadLevel.fromReadLevelType(consistencyType.getReadlevel());
}
final String elasticSetting = deployment.getCluster().getElastic().trim().toUpperCase();
if (elasticSetting.equals("ENABLED")) {
TheHashinator.setConfiguredHashinatorType(HashinatorType.ELASTIC);
} else if (!elasticSetting.equals("DISABLED")) {
VoltDB.crashLocalVoltDB("Error in deployment file, elastic attribute of " + "cluster element must be " + "'enabled' or 'disabled' but was '" + elasticSetting + "'", false, null);
} else {
TheHashinator.setConfiguredHashinatorType(HashinatorType.LEGACY);
}
// log system setting information
SystemSettingsType sysType = deployment.getSystemsettings();
if (sysType != null) {
if (sysType.getElastic() != null) {
hostLog.info("Elastic duration set to " + sysType.getElastic().getDuration() + " milliseconds");
hostLog.info("Elastic throughput set to " + sysType.getElastic().getThroughput() + " mb/s");
}
if (sysType.getTemptables() != null) {
hostLog.info("Max temptable size set to " + sysType.getTemptables().getMaxsize() + " mb");
}
if (sysType.getSnapshot() != null) {
hostLog.info("Snapshot priority set to " + sysType.getSnapshot().getPriority() + " [0 - 10]");
}
if (sysType.getQuery() != null) {
if (sysType.getQuery().getTimeout() > 0) {
hostLog.info("Query timeout set to " + sysType.getQuery().getTimeout() + " milliseconds");
m_config.m_queryTimeout = sysType.getQuery().getTimeout();
} else if (sysType.getQuery().getTimeout() == 0) {
hostLog.info("Query timeout set to unlimited");
m_config.m_queryTimeout = 0;
}
}
}
// log a warning on console log if security setting is turned off, like durability warning.
SecurityType securityType = deployment.getSecurity();
if (securityType == null || !securityType.isEnabled()) {
consoleLog.warn(SECURITY_OFF_WARNING);
}
// create a dummy catalog to load deployment info into
Catalog catalog = new Catalog();
// Need these in the dummy catalog
Cluster cluster = catalog.getClusters().add("cluster");
cluster.getDatabases().add("database");
String result = CatalogUtil.compileDeployment(catalog, deployment, true);
if (result != null) {
// Any other non-enterprise deployment errors will be caught and handled here
// (such as <= 0 host count)
VoltDB.crashLocalVoltDB(result);
}
m_catalogContext = new CatalogContext(//txnid
TxnEgo.makeZero(MpInitiator.MP_INIT_PID).getTxnId(), //timestamp
0, catalog, new DbSettings(m_clusterSettings, m_nodeSettings), new byte[] {}, null, deploymentBytes, 0, m_messenger);
return ((deployment.getCommandlog() != null) && (deployment.getCommandlog().isEnabled()));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
use of org.apache.zookeeper_voltpatches.ZooKeeper in project voltdb by VoltDB.
the class UpdateCore method run.
/**
* Parameters to run are provided internally and do not map to the
* user's input.
* @param ctx
* @param catalogDiffCommands
* @param catalogURL
* @param expectedCatalogVersion
* @return Standard STATUS table.
*/
@SuppressWarnings("deprecation")
public VoltTable[] run(SystemProcedureExecutionContext ctx, String catalogDiffCommands, byte[] catalogHash, byte[] catalogBytes, int expectedCatalogVersion, String deploymentString, String[] tablesThatMustBeEmpty, String[] reasonsForEmptyTables, byte requiresSnapshotIsolation, byte worksWithElastic, byte[] deploymentHash, byte requireCatalogDiffCmdsApplyToEE, byte hasSchemaChange, byte requiresNewExportGeneration) throws Exception {
assert (tablesThatMustBeEmpty != null);
/*
* Validate that no elastic join is in progress, blocking this catalog update.
* If this update works with elastic then do the update anyways
*/
ZooKeeper zk = VoltDB.instance().getHostMessenger().getZK();
if (worksWithElastic == 0 && !zk.getChildren(VoltZK.catalogUpdateBlockers, false).isEmpty()) {
throw new VoltAbortException("Can't do a catalog update while an elastic join or rejoin is active");
}
// write uac blocker zk node
VoltZK.createCatalogUpdateBlocker(zk, VoltZK.uacActiveBlocker);
// check rejoin blocker node
if (zk.exists(VoltZK.rejoinActiveBlocker, false) != null) {
VoltZK.removeCatalogUpdateBlocker(zk, VoltZK.uacActiveBlocker, log);
throw new VoltAbortException("Can't do a catalog update while an elastic join or rejoin is active");
}
try {
// Pull the current catalog and deployment version and hash info. Validate that we're either:
// (a) starting a new, valid catalog or deployment update
// (b) restarting a valid catalog or deployment update
// otherwise, we can bomb out early. This should guarantee that we only
// ever write valid catalog and deployment state to ZK.
CatalogAndIds catalogStuff = CatalogUtil.getCatalogFromZK(zk);
// New update?
if (catalogStuff.version == expectedCatalogVersion) {
if (log.isInfoEnabled()) {
log.info("New catalog update from: " + catalogStuff.toString());
log.info("To: catalog hash: " + Encoder.hexEncode(catalogHash).substring(0, 10) + ", deployment hash: " + Encoder.hexEncode(deploymentHash).substring(0, 10));
}
} else // restart?
{
if (catalogStuff.version == (expectedCatalogVersion + 1) && Arrays.equals(catalogStuff.getCatalogHash(), catalogHash) && Arrays.equals(catalogStuff.getDeploymentHash(), deploymentHash)) {
if (log.isInfoEnabled()) {
log.info("Restarting catalog update: " + catalogStuff.toString());
}
} else {
String errmsg = "Invalid catalog update. Catalog or deployment change was planned " + "against one version of the cluster configuration but that version was " + "no longer live when attempting to apply the change. This is likely " + "the result of multiple concurrent attempts to change the cluster " + "configuration. Please make such changes synchronously from a single " + "connection to the cluster.";
log.warn(errmsg);
throw new VoltAbortException(errmsg);
}
}
byte[] deploymentBytes = deploymentString.getBytes("UTF-8");
// update the global version. only one site per node will accomplish this.
// others will see there is no work to do and gracefully continue.
// then update data at the local site.
CatalogUtil.updateCatalogToZK(zk, expectedCatalogVersion + 1, DeprecatedProcedureAPIAccess.getVoltPrivateRealTransactionId(this), getUniqueId(), catalogBytes, catalogHash, deploymentBytes);
try {
performCatalogVerifyWork(expectedCatalogVersion, tablesThatMustBeEmpty, reasonsForEmptyTables, requiresSnapshotIsolation);
} catch (VoltAbortException vae) {
// If there is a cluster failure before this point, we will re-run
// the transaction with the same input args and the new state,
// which we will recognize as a restart and do the right thing.
log.debug("Catalog update cannot be applied. Rolling back ZK state");
CatalogUtil.updateCatalogToZK(zk, catalogStuff.version, catalogStuff.txnId, catalogStuff.uniqueId, catalogStuff.catalogBytes, catalogStuff.getCatalogHash(), catalogStuff.deploymentBytes);
// hopefully this will throw a SpecifiedException if the fragment threw one
throw vae;
// If there is a cluster failure after this point, we will re-run
// the transaction with the same input args and the old state,
// which will look like a new UAC transaction. If there is no
// cluster failure, we leave the ZK state consistent with the
// catalog state which we entered here with.
}
performCatalogUpdateWork(catalogDiffCommands, expectedCatalogVersion, requiresSnapshotIsolation, requireCatalogDiffCmdsApplyToEE, hasSchemaChange, requiresNewExportGeneration);
} finally {
// remove the uac blocker when exits
VoltZK.removeCatalogUpdateBlocker(zk, VoltZK.uacActiveBlocker, log);
}
// This is when the UpdateApplicationCatalog really ends in the blocking path
log.info(String.format("Globally updating the current application catalog and deployment " + "(new hashes %s, %s).", Encoder.hexEncode(catalogHash).substring(0, 10), Encoder.hexEncode(deploymentHash).substring(0, 10)));
VoltTable result = new VoltTable(VoltSystemProcedure.STATUS_SCHEMA);
result.addRow(VoltSystemProcedure.STATUS_OK);
return (new VoltTable[] { result });
}
use of org.apache.zookeeper_voltpatches.ZooKeeper in project voltdb by VoltDB.
the class Pause method run.
/**
* Enter admin mode
* @param ctx Internal parameter. Not user-accessible.
* @return Standard STATUS table.
*/
public VoltTable[] run(SystemProcedureExecutionContext ctx) {
if (ctx.isLowestSiteId()) {
VoltDBInterface voltdb = VoltDB.instance();
OperationMode opMode = voltdb.getMode();
if (LOG.isDebugEnabled()) {
LOG.debug("voltdb opmode is " + opMode);
}
ZooKeeper zk = voltdb.getHostMessenger().getZK();
try {
Stat stat;
OperationMode zkMode = null;
Code code;
do {
stat = new Stat();
code = Code.BADVERSION;
try {
byte[] data = zk.getData(VoltZK.operationMode, false, stat);
if (LOG.isDebugEnabled()) {
LOG.debug("zkMode is " + (zkMode == null ? "(null)" : OperationMode.valueOf(data)));
}
zkMode = data == null ? opMode : OperationMode.valueOf(data);
if (zkMode == PAUSED) {
if (LOG.isDebugEnabled()) {
LOG.debug("read node at version " + stat.getVersion() + ", txn " + ll(stat.getMzxid()));
}
break;
}
stat = zk.setData(VoltZK.operationMode, PAUSED.getBytes(), stat.getVersion());
code = Code.OK;
zkMode = PAUSED;
if (LOG.isDebugEnabled()) {
LOG.debug("!WROTE! node at version " + stat.getVersion() + ", txn " + ll(stat.getMzxid()));
}
break;
} catch (BadVersionException ex) {
code = ex.code();
}
} while (zkMode != PAUSED && code == Code.BADVERSION);
m_stat = stat;
voltdb.getHostMessenger().pause();
voltdb.setMode(PAUSED);
// for snmp
SnmpTrapSender snmp = voltdb.getSnmpTrapSender();
if (snmp != null) {
snmp.pause("Cluster paused.");
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// Force a tick so that stats will be updated.
// Primarily added to get latest table stats for DR pause and empty db check.
ctx.getSiteProcedureConnection().tick();
VoltTable t = new VoltTable(VoltSystemProcedure.STATUS_SCHEMA);
t.addRow(VoltSystemProcedure.STATUS_OK);
return (new VoltTable[] { t });
}
use of org.apache.zookeeper_voltpatches.ZooKeeper in project voltdb by VoltDB.
the class Resume method run.
/**
* Exit admin mode
* @param ctx Internal parameter. Not user-accessible.
* @return Standard STATUS table.
*/
public VoltTable[] run(SystemProcedureExecutionContext ctx) {
// Choose the lowest site ID on this host to actually flip the bit
VoltDBInterface voltdb = VoltDB.instance();
OperationMode opMode = voltdb.getMode();
if (ctx.isLowestSiteId()) {
ZooKeeper zk = voltdb.getHostMessenger().getZK();
try {
Stat stat;
OperationMode zkMode = null;
Code code;
do {
stat = new Stat();
code = Code.BADVERSION;
try {
byte[] data = zk.getData(VoltZK.operationMode, false, stat);
zkMode = data == null ? opMode : OperationMode.valueOf(data);
if (zkMode == RUNNING) {
break;
}
stat = zk.setData(VoltZK.operationMode, RUNNING.getBytes(), stat.getVersion());
code = Code.OK;
zkMode = RUNNING;
break;
} catch (BadVersionException ex) {
code = ex.code();
}
} while (zkMode != RUNNING && code == Code.BADVERSION);
voltdb.getHostMessenger().unpause();
voltdb.setMode(RUNNING);
// for snmp
SnmpTrapSender snmp = voltdb.getSnmpTrapSender();
if (snmp != null) {
snmp.resume("Cluster resumed.");
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
VoltTable t = new VoltTable(VoltSystemProcedure.STATUS_SCHEMA);
t.addRow(VoltSystemProcedure.STATUS_OK);
return new VoltTable[] { t };
}
Aggregations