use of org.apache.asterix.common.cluster.ClusterPartition in project asterixdb by apache.
the class MetadataBootstrap method enlistMetadataDataset.
/**
* Enlist a metadata index so it is available for metadata operations
* should be performed upon bootstrapping
*
* @param index
* @throws HyracksDataException
*/
public static void enlistMetadataDataset(INCServiceContext ncServiceCtx, IMetadataIndex index) throws HyracksDataException {
ClusterPartition metadataPartition = appContext.getMetadataProperties().getMetadataPartition();
int metadataDeviceId = metadataPartition.getIODeviceNum();
String metadataPartitionPath = StoragePathUtil.prepareStoragePartitionPath(ClusterProperties.INSTANCE.getStorageDirectoryName(), metadataPartition.getPartitionId());
String resourceName = metadataPartitionPath + File.separator + index.getFileNameRelativePath();
FileReference file = ioManager.getFileReference(metadataDeviceId, resourceName);
index.setFile(file);
ITypeTraits[] typeTraits = index.getTypeTraits();
IBinaryComparatorFactory[] cmpFactories = index.getKeyBinaryComparatorFactory();
int[] bloomFilterKeyFields = index.getBloomFilterKeyFields();
// opTrackerProvider and ioOpCallbackFactory should both be acquired through IStorageManager
// We are unable to do this since IStorageManager needs a dataset to determine the appropriate
// objects
ILSMOperationTrackerFactory opTrackerFactory = index.isPrimaryIndex() ? new PrimaryIndexOperationTrackerFactory(index.getDatasetId().getId()) : new SecondaryIndexOperationTrackerFactory(index.getDatasetId().getId());
ILSMIOOperationCallbackFactory ioOpCallbackFactory = LSMBTreeIOOperationCallbackFactory.INSTANCE;
IStorageComponentProvider storageComponentProvider = appContext.getStorageComponentProvider();
if (isNewUniverse()) {
LSMBTreeLocalResourceFactory lsmBtreeFactory = new LSMBTreeLocalResourceFactory(storageComponentProvider.getStorageManager(), typeTraits, cmpFactories, null, null, null, opTrackerFactory, ioOpCallbackFactory, storageComponentProvider.getMetadataPageManagerFactory(), new AsterixVirtualBufferCacheProvider(index.getDatasetId().getId()), storageComponentProvider.getIoOperationSchedulerProvider(), appContext.getMetadataMergePolicyFactory(), GlobalConfig.DEFAULT_COMPACTION_POLICY_PROPERTIES, true, bloomFilterKeyFields, appContext.getBloomFilterFalsePositiveRate(), true, null);
DatasetLocalResourceFactory dsLocalResourceFactory = new DatasetLocalResourceFactory(index.getDatasetId().getId(), lsmBtreeFactory);
// TODO(amoudi) Creating the index should be done through the same code path as other indexes
// This is to be done by having a metadata dataset associated with each index
IIndexBuilder indexBuilder = new IndexBuilder(ncServiceCtx, storageComponentProvider.getStorageManager(), index::getResourceId, file, dsLocalResourceFactory, true);
indexBuilder.build();
} else {
final LocalResource resource = localResourceRepository.get(file.getRelativePath());
if (resource == null) {
throw new HyracksDataException("Could not find required metadata indexes. Please delete " + appContext.getMetadataProperties().getTransactionLogDirs().get(appContext.getTransactionSubsystem().getId()) + " to intialize as a new instance. (WARNING: all data will be lost.)");
}
// Why do we care about metadata dataset's resource ids? why not assign them ids similar to other resources?
if (index.getResourceId() != resource.getId()) {
throw new HyracksDataException("Resource Id doesn't match expected metadata index resource id");
}
IndexDataflowHelper indexHelper = new IndexDataflowHelper(ncServiceCtx, storageComponentProvider.getStorageManager(), file);
// Opening the index through the helper will ensure it gets instantiated
indexHelper.open();
indexHelper.close();
}
}
use of org.apache.asterix.common.cluster.ClusterPartition in project asterixdb by apache.
the class ClusterStateManager method resetClusterPartitionConstraint.
private synchronized void resetClusterPartitionConstraint() {
ArrayList<String> clusterActiveLocations = new ArrayList<>();
for (ClusterPartition p : clusterPartitions.values()) {
if (p.isActive()) {
clusterActiveLocations.add(p.getActiveNodeId());
}
}
clusterPartitionConstraint = new AlgebricksAbsolutePartitionConstraint(clusterActiveLocations.toArray(new String[] {}));
}
use of org.apache.asterix.common.cluster.ClusterPartition in project asterixdb by apache.
the class PropertiesAccessor method configureNc.
private void configureNc(ConfigManager configManager, String ncId, MutableInt uniquePartitionId) throws AsterixException {
// Now we assign the coredump and txnlog directories for this node.
// QQQ Default values? Should they be specified here? Or should there
// be a default.ini? Certainly wherever they are, they should be platform-dependent.
IApplicationConfig nodeCfg = cfg.getNCEffectiveConfig(ncId);
coredumpConfig.put(ncId, nodeCfg.getString(NodeProperties.Option.CORE_DUMP_DIR));
transactionLogDirs.put(ncId, nodeCfg.getString(NodeProperties.Option.TXN_LOG_DIR));
int partitionId = nodeCfg.getInt(NodeProperties.Option.STARTING_PARTITION_ID);
if (partitionId != -1) {
uniquePartitionId.setValue(partitionId);
} else {
configManager.set(ncId, NodeProperties.Option.STARTING_PARTITION_ID, uniquePartitionId.getValue());
}
// Now we create an array of ClusterPartitions for all the partitions
// on this NC.
String[] iodevices = nodeCfg.getStringArray(IODEVICES);
String storageSubdir = nodeCfg.getString(STORAGE_SUBDIR);
String[] nodeStores = new String[iodevices.length];
ClusterPartition[] nodePartitions = new ClusterPartition[iodevices.length];
for (int i = 0; i < nodePartitions.length; i++) {
// Construct final storage path from iodevice dir + storage subdirs
nodeStores[i] = iodevices[i] + File.separator + storageSubdir;
// Create ClusterPartition instances for this NC.
ClusterPartition partition = new ClusterPartition(uniquePartitionId.getAndIncrement(), ncId, i);
ClusterPartition orig = clusterPartitions.put(partition.getPartitionId(), partition);
if (orig != null) {
throw AsterixException.create(ErrorCode.DUPLICATE_PARTITION_ID, partition.getPartitionId(), ncId, orig.getNodeId());
}
nodePartitions[i] = partition;
}
stores.put(ncId, nodeStores);
nodePartitionsMap.put(ncId, nodePartitions);
}
use of org.apache.asterix.common.cluster.ClusterPartition in project asterixdb by apache.
the class RemoteRecoveryManager method completeFailbackProcess.
@Override
public void completeFailbackProcess() throws IOException, InterruptedException {
ILogManager logManager = runtimeContext.getTransactionSubsystem().getLogManager();
ReplicaResourcesManager replicaResourcesManager = (ReplicaResourcesManager) runtimeContext.getReplicaResourcesManager();
Map<String, ClusterPartition[]> nodePartitions = runtimeContext.getMetadataProperties().getNodePartitions();
/**
* for each lost partition, get the remaining files from replicas
* to complete the failback process.
*/
try {
for (Entry<String, Set<String>> remoteReplica : failbackRecoveryReplicas.entrySet()) {
String replicaId = remoteReplica.getKey();
Set<String> NCsDataToRecover = remoteReplica.getValue();
Set<String> existingFiles = new HashSet<>();
Set<Integer> partitionsToRecover = new HashSet<>();
for (String nodeId : NCsDataToRecover) {
//get partitions that will be recovered from this node
ClusterPartition[] replicaPartitions = nodePartitions.get(nodeId);
for (ClusterPartition partition : replicaPartitions) {
existingFiles.addAll(replicaResourcesManager.getPartitionIndexesFiles(partition.getPartitionId(), true));
partitionsToRecover.add(partition.getPartitionId());
}
}
//Request remaining indexes files
replicationManager.requestReplicaFiles(replicaId, partitionsToRecover, existingFiles);
}
} catch (IOException e) {
/**
* in case of failure during failback completion process we need to construct a new plan
* and get all the files from the start since the remote replicas will change in the new plan.
*/
if (LOGGER.isLoggable(Level.WARNING)) {
LOGGER.log(Level.WARNING, "Failed during completing failback. Restarting failback process...", e);
}
startFailbackProcess();
}
//get max LSN from selected remote replicas
long maxRemoteLSN = replicationManager.getMaxRemoteLSN(failbackRecoveryReplicas.keySet());
//6. force LogManager to start from a partition > maxLSN in selected remote replicas
logManager.renewLogFilesAndStartFromLSN(maxRemoteLSN);
//start replication service after failback completed
runtimeContext.getReplicationChannel().start();
runtimeContext.getReplicationManager().startReplicationThreads();
failbackRecoveryReplicas = null;
}
use of org.apache.asterix.common.cluster.ClusterPartition in project asterixdb by apache.
the class RemoteRecoveryManager method startFailbackProcess.
@Override
public void startFailbackProcess() {
int maxRecoveryAttempts = replicationProperties.getMaxRemoteRecoveryAttempts();
PersistentLocalResourceRepository resourceRepository = (PersistentLocalResourceRepository) runtimeContext.getLocalResourceRepository();
IDatasetLifecycleManager datasetLifeCycleManager = runtimeContext.getDatasetLifecycleManager();
Map<String, ClusterPartition[]> nodePartitions = runtimeContext.getMetadataProperties().getNodePartitions();
while (true) {
//start recovery steps
try {
if (maxRecoveryAttempts <= 0) {
//to avoid infinite loop in case of unexpected behavior.
throw new IllegalStateException("Failed to perform remote recovery.");
}
/*** Prepare for Recovery ***/
//1. check remote replicas states
replicationManager.initializeReplicasState();
int activeReplicasCount = replicationManager.getActiveReplicasCount();
if (activeReplicasCount == 0) {
throw new IllegalStateException("no ACTIVE remote replica(s) exists to perform remote recovery");
}
//2. clean any memory data that could've existed from previous failed recovery attempt
datasetLifeCycleManager.closeAllDatasets();
//3. remove any existing storage data and initialize storage metadata
resourceRepository.deleteStorageData(true);
resourceRepository.initializeNewUniverse(ClusterProperties.INSTANCE.getStorageDirectoryName());
//4. select remote replicas to recover from per lost replica data
failbackRecoveryReplicas = constructRemoteRecoveryPlan();
/*** Start Recovery Per Lost Replica ***/
for (Entry<String, Set<String>> remoteReplica : failbackRecoveryReplicas.entrySet()) {
String replicaId = remoteReplica.getKey();
Set<String> ncsToRecoverFor = remoteReplica.getValue();
Set<Integer> partitionsIds = new HashSet<>();
for (String node : ncsToRecoverFor) {
partitionsIds.addAll((Arrays.asList(nodePartitions.get(node))).stream().map(ClusterPartition::getPartitionId).collect(Collectors.toList()));
}
//1. Request indexes metadata and LSM components
replicationManager.requestReplicaFiles(replicaId, partitionsIds, new HashSet<String>());
}
break;
} catch (IOException e) {
if (LOGGER.isLoggable(Level.WARNING)) {
LOGGER.log(Level.WARNING, "Failed during remote recovery. Attempting again...", e);
}
maxRecoveryAttempts--;
}
}
}
Aggregations