private synchronized void scheduleSnapshotIfNeeded() { if (!shardGateway.requiresSnapshot()) { return; } if (!shardGateway.requiresSnapshotScheduling()) { return; } if (!indexShard.routingEntry().primary()) { // we only do snapshotting on the primary shard return; } if (!indexShard.routingEntry().started()) { // we only schedule when the cluster assumes we have started return; } if (snapshotScheduleFuture != null) { // we are already scheduling this one, ignore return; } if (snapshotInterval.millis() != -1) { // we need to schedule snapshot if (logger.isDebugEnabled()) { logger.debug("scheduling snapshot every [{}]", snapshotInterval); } snapshotScheduleFuture = threadPool.schedule(snapshotInterval, ThreadPool.Names.SNAPSHOT, snapshotRunnable); } }
public SnapshotStatus snapshotStatus() { SnapshotStatus snapshotStatus = shardGateway.currentSnapshotStatus(); if (snapshotStatus != null) { return snapshotStatus; } return shardGateway.lastSnapshotStatus(); }
public void snapshotOnClose() { if (shardGateway.requiresSnapshot() && snapshotOnClose) { try { snapshot("shutdown"); } catch (Exception e) { logger.warn("failed to snapshot on close", e); } } }
@Override public synchronized void close() { indexSettingsService.removeListener(applySettings); if (snapshotScheduleFuture != null) { snapshotScheduleFuture.cancel(true); snapshotScheduleFuture = null; } shardGateway.close(); if (snapshotLock != null) { snapshotLock.release(); } }
/** Snapshots the given shard into the gateway. */ public synchronized void snapshot(final String reason) throws IndexShardGatewaySnapshotFailedException { if (!indexShard.routingEntry().primary()) { return; // throw new IndexShardGatewaySnapshotNotAllowedException(shardId, "Snapshot not // allowed on non primary shard"); } if (indexShard.routingEntry().relocating()) { // do not snapshot when in the process of relocation of primaries so we won't get conflicts return; } if (indexShard.state() == IndexShardState.CREATED) { // shard has just been created, ignore it and return return; } if (indexShard.state() == IndexShardState.RECOVERING) { // shard is recovering, don't snapshot return; } if (snapshotLock == null) { try { snapshotLock = shardGateway.obtainSnapshotLock(); } catch (Exception e) { logger.warn("failed to obtain snapshot lock, ignoring snapshot", e); return; } } try { SnapshotStatus snapshotStatus = indexShard.snapshot( new Engine.SnapshotHandler<SnapshotStatus>() { @Override public SnapshotStatus snapshot( SnapshotIndexCommit snapshotIndexCommit, Translog.Snapshot translogSnapshot) throws EngineException { if (lastIndexVersion != snapshotIndexCommit.getGeneration() || lastTranslogId != translogSnapshot.translogId() || lastTranslogLength < translogSnapshot.length()) { logger.debug("snapshot ({}) to {} ...", reason, shardGateway); SnapshotStatus snapshotStatus = shardGateway.snapshot( new IndexShardGateway.Snapshot( snapshotIndexCommit, translogSnapshot, lastIndexVersion, lastTranslogId, lastTranslogLength, lastTotalTranslogOperations)); lastIndexVersion = snapshotIndexCommit.getGeneration(); lastTranslogId = translogSnapshot.translogId(); lastTranslogLength = translogSnapshot.length(); lastTotalTranslogOperations = translogSnapshot.estimatedTotalOperations(); return snapshotStatus; } return null; } }); if (snapshotStatus != null) { if (logger.isDebugEnabled()) { StringBuilder sb = new StringBuilder(); sb.append("snapshot (") .append(reason) .append(") completed to ") .append(shardGateway) .append(", took [") .append(TimeValue.timeValueMillis(snapshotStatus.time())) .append("]\n"); sb.append(" index : version [") .append(lastIndexVersion) .append("], number_of_files [") .append(snapshotStatus.index().numberOfFiles()) .append("] with total_size [") .append(new ByteSizeValue(snapshotStatus.index().totalSize())) .append("], took [") .append(TimeValue.timeValueMillis(snapshotStatus.index().time())) .append("]\n"); sb.append(" translog : id [") .append(lastTranslogId) .append("], number_of_operations [") .append(snapshotStatus.translog().expectedNumberOfOperations()) .append("], took [") .append(TimeValue.timeValueMillis(snapshotStatus.translog().time())) .append("]"); logger.debug(sb.toString()); } } } catch (SnapshotFailedEngineException e) { if (e.getCause() instanceof IllegalStateException) { // ignore, that's fine, snapshot has not started yet } else { throw new IndexShardGatewaySnapshotFailedException(shardId, "Failed to snapshot", e); } } catch (IllegalIndexShardStateException e) { // ignore, that's fine, snapshot has not started yet } catch (IndexShardGatewaySnapshotFailedException e) { throw e; } catch (Exception e) { throw new IndexShardGatewaySnapshotFailedException(shardId, "Failed to snapshot", e); } }