use of org.voltdb.client.ProcedureCallback in project voltdb by VoltDB.
the class SnapshotDaemon method initiateNextSnapshot.
private void initiateNextSnapshot(long now) {
setState(State.SNAPSHOTTING);
m_lastSysprocInvocation = now;
final Date nowDate = new Date(now);
final String dateString = m_dateFormat.format(nowDate);
final String nonce = m_prefix + dateString;
JSONObject jsObj = new JSONObject();
try {
jsObj.put(SnapshotUtil.JSON_PATH, m_path);
jsObj.put(SnapshotUtil.JSON_PATH_TYPE, SnapshotPathType.SNAP_AUTO.toString());
jsObj.put(SnapshotUtil.JSON_NONCE, nonce);
jsObj.put("perPartitionTxnIds", retrievePerPartitionTransactionIds());
m_snapshots.offer(new Snapshot(m_path, SnapshotPathType.SNAP_AUTO, nonce, now));
long handle = m_nextCallbackHandle++;
m_procedureCallbacks.put(handle, new ProcedureCallback() {
@Override
public void clientCallback(final ClientResponse clientResponse) throws Exception {
m_lastInitiationTs = null;
processClientResponsePrivate(clientResponse);
}
});
SNAP_LOG.info("Requesting auto snapshot to path " + m_path + " nonce " + nonce);
initiateSnapshotSave(handle, new Object[] { jsObj.toString(4) }, false);
} catch (JSONException e) {
/*
* Should never happen, so fail fast
*/
VoltDB.crashLocalVoltDB("", false, e);
}
}
use of org.voltdb.client.ProcedureCallback in project voltdb by VoltDB.
the class SnapshotDaemon method groomTruncationSnapshots.
/*
* Delete all snapshots older then the last successful snapshot.
* This only effects snapshots used for log truncation
*/
private void groomTruncationSnapshots() {
ArrayList<TruncationSnapshotAttempt> toDelete = new ArrayList<TruncationSnapshotAttempt>();
boolean foundMostRecentSuccess = false;
Iterator<Map.Entry<Long, TruncationSnapshotAttempt>> iter = m_truncationSnapshotAttempts.descendingMap().entrySet().iterator();
loggingLog.info("Snapshot daemon grooming truncation snapshots");
while (iter.hasNext()) {
Map.Entry<Long, TruncationSnapshotAttempt> entry = iter.next();
TruncationSnapshotAttempt snapshotAttempt = entry.getValue();
if (!foundMostRecentSuccess) {
if (snapshotAttempt.finished) {
loggingLog.info("Found most recent successful snapshot txnid " + TxnEgo.txnIdToString(entry.getKey()) + " path " + entry.getValue().path + " nonce " + entry.getValue().nonce);
foundMostRecentSuccess = true;
} else {
loggingLog.info("Retaining possible partial snapshot txnid " + TxnEgo.txnIdToString(entry.getKey()) + " path " + entry.getValue().path + " nonce " + entry.getValue().nonce);
}
} else {
loggingLog.info("Deleting old unecessary snapshot txnid " + TxnEgo.txnIdToString(entry.getKey()) + " path " + entry.getValue().path + " nonce " + entry.getValue().nonce);
toDelete.add(entry.getValue());
iter.remove();
}
}
String[] paths = new String[toDelete.size()];
String[] nonces = new String[toDelete.size()];
int ii = 0;
for (TruncationSnapshotAttempt attempt : toDelete) {
paths[ii] = attempt.path;
paths[ii] = SnapshotUtil.getRealPath(SnapshotPathType.valueOf(attempt.pathType), paths[ii]);
nonces[ii++] = attempt.nonce;
}
Object[] params = new Object[] { paths, nonces, SnapshotPathType.SNAP_CL.toString() };
long handle = m_nextCallbackHandle++;
m_procedureCallbacks.put(handle, new ProcedureCallback() {
@Override
public void clientCallback(ClientResponse clientResponse) throws Exception {
if (clientResponse.getStatus() != ClientResponse.SUCCESS) {
SNAP_LOG.error(clientResponse.getStatusString());
}
}
});
m_initiator.initiateSnapshotDaemonWork("@SnapshotDelete", handle, params);
}
use of org.voltdb.client.ProcedureCallback in project voltdb by VoltDB.
the class SnapshotDaemon method processSnapshotTruncationRequestCreated.
/*
* A ZK event occured requestion a truncation snapshot be taken
*/
private void processSnapshotTruncationRequestCreated(final WatchedEvent event) {
loggingLog.info("Snapshot truncation leader received snapshot truncation request");
// Get the truncation request ID which is the truncation request node path.
final String truncReqId;
try {
List<String> children = m_zk.getChildren(event.getPath(), false);
if (children.isEmpty()) {
loggingLog.error("Unable to retrieve truncation snapshot request id from ZK, log can't be truncated");
return;
}
truncReqId = ZKUtil.joinZKPath(event.getPath(), Collections.max(children));
} catch (Exception e) {
loggingLog.error("Unable to retrieve truncation snapshot request ID from ZK, log can't be truncated");
return;
}
final long now = System.currentTimeMillis();
final String nonce = Long.toString(now);
// TRAIL [TruncSnap:7] write current ts to request zk node data
try {
ByteBuffer payload = ByteBuffer.allocate(8);
payload.putLong(0, now);
m_zk.setData(VoltZK.request_truncation_snapshot, payload.array(), -1);
} catch (Exception e) {
//Cause a cascading failure?
VoltDB.crashLocalVoltDB("Setting data on the truncation snapshot request in ZK should never fail", true, e);
}
// for the snapshot save invocations
JSONObject jsObj = new JSONObject();
try {
assert truncReqId != null;
String sData = "";
JSONObject jsData = new JSONObject();
jsData.put("truncReqId", truncReqId);
sData = jsData.toString();
jsObj.put(SnapshotUtil.JSON_PATH, VoltDB.instance().getCommandLogSnapshotPath());
jsObj.put(SnapshotUtil.JSON_NONCE, nonce);
jsObj.put(SnapshotUtil.JSON_PATH_TYPE, SnapshotPathType.SNAP_CL);
jsObj.put("perPartitionTxnIds", retrievePerPartitionTransactionIds());
jsObj.put("data", sData);
} catch (JSONException e) {
/*
* Should never happen, so fail fast
*/
VoltDB.crashLocalVoltDB("", true, e);
}
// for the snapshot save invocations
long handle = m_nextCallbackHandle++;
// for the snapshot save invocation
m_procedureCallbacks.put(handle, new ProcedureCallback() {
@Override
public void clientCallback(ClientResponse clientResponse) throws Exception {
m_lastInitiationTs = null;
if (clientResponse.getStatus() != ClientResponse.SUCCESS) {
loggingLog.warn("Attempt to initiate a truncation snapshot was not successful: " + clientResponse.getStatusString());
loggingLog.warn("Retrying log truncation snapshot in 5 minutes");
/*
* TRAIL [TruncSnap:8] (callback) on failed response try again in a few minute
*/
m_es.schedule(new Runnable() {
@Override
public void run() {
try {
processTruncationRequestEvent(event);
} catch (Exception e) {
VoltDB.crashLocalVoltDB("Error processing snapshot truncation request event", true, e);
}
}
}, 5, TimeUnit.MINUTES);
return;
}
final VoltTable[] results = clientResponse.getResults();
final VoltTable result = results[0];
boolean success = true;
final String err = SnapshotUtil.didSnapshotRequestFailWithErr(results);
if (err != null) {
if (err.trim().equalsIgnoreCase("SNAPSHOT IN PROGRESS")) {
loggingLog.info("Snapshot is in progress");
} else {
loggingLog.warn("Snapshot failed with failure response: " + err);
}
success = false;
}
//assert(result.getColumnName(1).equals("TABLE"));
if (success) {
while (result.advanceRow()) {
if (!result.getString("RESULT").equals("SUCCESS")) {
success = false;
loggingLog.warn("Snapshot save feasibility test failed for host " + result.getLong("HOST_ID") + " table " + result.getString("TABLE") + " with error message " + result.getString("ERR_MSG"));
}
}
}
if (success) {
loggingLog.info("Snapshot initiation for log truncation was successful");
JSONObject obj = new JSONObject(clientResponse.getAppStatusString());
final long snapshotTxnId = Long.valueOf(obj.getLong("txnId"));
try {
boolean found = false;
ZKUtil.VoidCallback lastCallback = null;
for (String child : m_zk.getChildren(event.getPath(), false)) {
String requestId = ZKUtil.joinZKPath(event.getPath(), child);
found = found || requestId.equals(truncReqId);
lastCallback = new ZKUtil.VoidCallback();
m_zk.delete(requestId, -1, lastCallback, null);
}
if (lastCallback != null) {
try {
lastCallback.get();
} catch (KeeperException.NoNodeException ignoreIt) {
}
}
if (!found) {
VoltDB.crashLocalVoltDB("Could not match truncations snapshot request id while atepting its removal", true, null);
}
} catch (Exception e) {
VoltDB.crashLocalVoltDB("Unexpected error deleting truncation snapshot request", true, e);
}
try {
TruncationSnapshotAttempt snapshotAttempt = m_truncationSnapshotAttempts.get(snapshotTxnId);
if (snapshotAttempt == null) {
snapshotAttempt = new TruncationSnapshotAttempt();
m_truncationSnapshotAttempts.put(snapshotTxnId, snapshotAttempt);
snapshotAttempt.pathType = SnapshotPathType.SNAP_CL.toString();
}
snapshotAttempt.nonce = nonce;
snapshotAttempt.path = VoltDB.instance().getCommandLogSnapshotPath();
} finally {
// TRAIL [TruncSnap:9] (callback) restart the whole request check cycle
try {
truncationRequestExistenceCheck();
} catch (Exception e) {
VoltDB.crashLocalVoltDB("Unexpected error checking for existence of truncation snapshot request", true, e);
}
}
} else {
loggingLog.info("Retrying log truncation snapshot in 60 seconds");
/*
* TRAIL [TruncSnap:10] (callback) on table reported failure try again in a few minutes
*/
m_es.schedule(new Runnable() {
@Override
public void run() {
try {
processTruncationRequestEvent(event);
} catch (Exception e) {
VoltDB.crashLocalVoltDB("Exception processing truncation request event", true, e);
}
}
}, 1, TimeUnit.MINUTES);
}
}
});
try {
loggingLog.info("Initiating @SnapshotSave for log truncation");
initiateSnapshotSave(handle, new Object[] { jsObj.toString(4) }, false);
} catch (JSONException e) {
/*
* Should never happen, so fail fast
*/
VoltDB.crashLocalVoltDB("", true, e);
}
return;
}
use of org.voltdb.client.ProcedureCallback in project voltdb by VoltDB.
the class LightweightNTClientResponseAdapter method enqueue.
@Override
public void enqueue(final ByteBuffer b) {
final ClientResponseImpl resp = new ClientResponseImpl();
b.position(4);
try {
resp.initFromBuffer(b);
} catch (IOException ex) {
VoltDB.crashLocalVoltDB("enqueue() in InternalClientResponseAdapter throw an exception", true, ex);
}
final ProcedureCallback callback = m_callbacks.remove(resp.getClientHandle());
if (callback == null) {
assert (false);
throw new IllegalStateException("Callback was null?");
}
try {
callback.clientCallback(resp);
} catch (Exception ex) {
assert (false);
m_logger.error("Failed to process callback.", ex);
}
}
use of org.voltdb.client.ProcedureCallback in project voltdb by VoltDB.
the class TableHelper method deleteEveryNRows.
/**
* Delete rows in a VoltDB table that has a bigint pkey where pkey values are odd.
* Works best when pkey values are contiguous and start around 0.
*
* Exists mostly to force compaction on tables loaded with fillTableWithBigintPkey.
* Though if you have an even number of sites, this won't work. It'll need to be
* updated to delete some other pattern that's a bit more generic. Right now it
* works great for my one-site testing.
*
*/
public static long deleteEveryNRows(VoltTable table, Client client, int n) throws Exception {
// find the primary key, assume first col if not found
int pkeyColIndex = getBigintPrimaryKeyIndexIfExists(table);
if (pkeyColIndex == -1) {
pkeyColIndex = 0;
assert (table.getColumnType(0).isBackendIntegerType());
}
String pkeyColName = table.getColumnName(pkeyColIndex);
VoltTable result = client.callProcedure("@AdHoc", String.format("select %s from %s order by %s desc limit 1;", pkeyColName, TableHelper.getTableName(table), pkeyColName)).getResults()[0];
long maxId = result.getRowCount() > 0 ? result.asScalarLong() : 0;
System.out.printf("Deleting odd rows with pkey ids in the range 0-%d\n", maxId);
// track outstanding responses so 10k can be out at a time
final AtomicInteger outstanding = new AtomicInteger(0);
final AtomicLong deleteCount = new AtomicLong(0);
ProcedureCallback callback = new ProcedureCallback() {
@Override
public void clientCallback(ClientResponse clientResponse) throws Exception {
outstanding.decrementAndGet();
if (clientResponse.getStatus() != ClientResponse.SUCCESS) {
System.out.println("Error in deleter callback:");
System.out.println(((ClientResponseImpl) clientResponse).toJSONString());
assert (false);
}
VoltTable result = clientResponse.getResults()[0];
long modified = result.asScalarLong();
assert (modified <= 1);
deleteCount.addAndGet(modified);
}
};
// delete 100k rows at a time until nothing comes back
long deleted = 0;
final String deleteProcName = table.m_extraMetadata.name.toUpperCase() + ".delete";
for (int i = 1; i <= maxId; i += n) {
client.callProcedure(callback, deleteProcName, i);
outstanding.incrementAndGet();
deleted++;
if ((deleted % 100000) == 0) {
System.out.printf("Sent %d total delete invocations (%.1f%% of range).\n", deleted, (i * 100.0) / maxId);
}
// block while 1000 txns are outstanding
while (outstanding.get() >= 1000) {
Thread.yield();
}
}
// block until all calls have returned
while (outstanding.get() > 0) {
Thread.yield();
}
System.out.printf("Deleted %d odd rows\n", deleteCount.get());
return deleteCount.get();
}
Aggregations