Search in sources :

Example 1 with IRecoveryManager

use of org.apache.asterix.common.transactions.IRecoveryManager in project asterixdb by apache.

the class NCApplication method start.

@Override
public void start(IServiceContext serviceCtx, String[] args) throws Exception {
    if (args.length > 0) {
        throw new IllegalArgumentException("Unrecognized argument(s): " + Arrays.toString(args));
    }
    this.ncServiceCtx = (INCServiceContext) serviceCtx;
    ncServiceCtx.setThreadFactory(new AsterixThreadFactory(ncServiceCtx.getThreadFactory(), ncServiceCtx.getLifeCycleComponentManager()));
    nodeId = this.ncServiceCtx.getNodeId();
    if (LOGGER.isLoggable(Level.INFO)) {
        LOGGER.info("Starting Asterix node controller: " + nodeId);
    }
    configureLoggingLevel(ncServiceCtx.getAppConfig().getLoggingLevel(ExternalProperties.Option.LOG_LEVEL));
    final NodeControllerService controllerService = (NodeControllerService) ncServiceCtx.getControllerService();
    if (System.getProperty("java.rmi.server.hostname") == null) {
        System.setProperty("java.rmi.server.hostname", (controllerService).getConfiguration().getClusterPublicAddress());
    }
    runtimeContext = new NCAppRuntimeContext(this.ncServiceCtx, getExtensions());
    MetadataProperties metadataProperties = runtimeContext.getMetadataProperties();
    if (!metadataProperties.getNodeNames().contains(this.ncServiceCtx.getNodeId())) {
        if (LOGGER.isLoggable(Level.INFO)) {
            LOGGER.info("Substitute node joining : " + this.ncServiceCtx.getNodeId());
        }
        updateOnNodeJoin();
    }
    runtimeContext.initialize(runtimeContext.getNodeProperties().isInitialRun());
    MessagingProperties messagingProperties = runtimeContext.getMessagingProperties();
    IMessageBroker messageBroker = new NCMessageBroker(controllerService, messagingProperties);
    this.ncServiceCtx.setMessageBroker(messageBroker);
    MessagingChannelInterfaceFactory interfaceFactory = new MessagingChannelInterfaceFactory((NCMessageBroker) messageBroker, messagingProperties);
    this.ncServiceCtx.setMessagingChannelInterfaceFactory(interfaceFactory);
    IRecoveryManager recoveryMgr = runtimeContext.getTransactionSubsystem().getRecoveryManager();
    systemState = recoveryMgr.getSystemState();
    if (systemState == SystemState.PERMANENT_DATA_LOSS) {
        if (LOGGER.isLoggable(Level.INFO)) {
            LOGGER.info("System state: " + SystemState.PERMANENT_DATA_LOSS);
            LOGGER.info("Node ID: " + nodeId);
            LOGGER.info("Stores: " + PrintUtil.toString(metadataProperties.getStores()));
            LOGGER.info("Root Metadata Store: " + metadataProperties.getStores().get(nodeId)[0]);
        }
        PersistentLocalResourceRepository localResourceRepository = (PersistentLocalResourceRepository) runtimeContext.getLocalResourceRepository();
        localResourceRepository.initializeNewUniverse(ClusterProperties.INSTANCE.getStorageDirectoryName());
    }
    webManager = new WebManager();
    performLocalCleanUp();
}
Also used : NodeControllerService(org.apache.hyracks.control.nc.NodeControllerService) PersistentLocalResourceRepository(org.apache.asterix.transaction.management.resource.PersistentLocalResourceRepository) MessagingChannelInterfaceFactory(org.apache.asterix.messaging.MessagingChannelInterfaceFactory) WebManager(org.apache.hyracks.http.server.WebManager) NCAppRuntimeContext(org.apache.asterix.app.nc.NCAppRuntimeContext) IMessageBroker(org.apache.hyracks.api.messages.IMessageBroker) MetadataProperties(org.apache.asterix.common.config.MetadataProperties) NCMessageBroker(org.apache.asterix.messaging.NCMessageBroker) AsterixThreadFactory(org.apache.asterix.common.api.AsterixThreadFactory) MessagingProperties(org.apache.asterix.common.config.MessagingProperties) IRecoveryManager(org.apache.asterix.common.transactions.IRecoveryManager)

Example 2 with IRecoveryManager

use of org.apache.asterix.common.transactions.IRecoveryManager in project asterixdb by apache.

the class NCAppRuntimeContext method initialize.

@Override
public void initialize(boolean initialRun) throws IOException, ACIDException {
    ioManager = getServiceContext().getIoManager();
    threadExecutor = new ThreadExecutor(getServiceContext().getThreadFactory());
    fileMapManager = new FileMapManager(ioManager);
    ICacheMemoryAllocator allocator = new HeapBufferAllocator();
    IPageCleanerPolicy pcp = new DelayPageCleanerPolicy(600000);
    IPageReplacementStrategy prs = new ClockPageReplacementStrategy(allocator, storageProperties.getBufferCachePageSize(), storageProperties.getBufferCacheNumPages());
    AsynchronousScheduler.INSTANCE.init(getServiceContext().getThreadFactory());
    lsmIOScheduler = AsynchronousScheduler.INSTANCE;
    metadataMergePolicyFactory = new PrefixMergePolicyFactory();
    ILocalResourceRepositoryFactory persistentLocalResourceRepositoryFactory = new PersistentLocalResourceRepositoryFactory(ioManager, getServiceContext().getNodeId(), metadataProperties);
    localResourceRepository = (PersistentLocalResourceRepository) persistentLocalResourceRepositoryFactory.createRepository();
    IAppRuntimeContextProvider asterixAppRuntimeContextProvider = new AppRuntimeContextProviderForRecovery(this);
    txnSubsystem = new TransactionSubsystem(getServiceContext(), getServiceContext().getNodeId(), asterixAppRuntimeContextProvider, txnProperties);
    IRecoveryManager recoveryMgr = txnSubsystem.getRecoveryManager();
    SystemState systemState = recoveryMgr.getSystemState();
    if (initialRun || systemState == SystemState.PERMANENT_DATA_LOSS) {
        //delete any storage data before the resource factory is initialized
        localResourceRepository.deleteStorageData(true);
    }
    datasetLifecycleManager = new DatasetLifecycleManager(storageProperties, localResourceRepository, MetadataIndexImmutableProperties.FIRST_AVAILABLE_USER_DATASET_ID, txnSubsystem.getLogManager(), ioManager.getIODevices().size());
    isShuttingdown = false;
    activeManager = new ActiveManager(threadExecutor, getServiceContext().getNodeId(), activeProperties.getMemoryComponentGlobalBudget(), compilerProperties.getFrameSize());
    if (replicationProperties.isParticipant(getServiceContext().getNodeId())) {
        String nodeId = getServiceContext().getNodeId();
        replicaResourcesManager = new ReplicaResourcesManager(localResourceRepository, metadataProperties);
        replicationManager = new ReplicationManager(nodeId, replicationProperties, replicaResourcesManager, txnSubsystem.getLogManager(), asterixAppRuntimeContextProvider);
        //pass replication manager to replication required object
        //LogManager to replicate logs
        txnSubsystem.getLogManager().setReplicationManager(replicationManager);
        //PersistentLocalResourceRepository to replicate metadata files and delete backups on drop index
        localResourceRepository.setReplicationManager(replicationManager);
        /*
             * add the partitions that will be replicated in this node as inactive partitions
             */
        //get nodes which replicate to this node
        Set<String> remotePrimaryReplicas = replicationProperties.getRemotePrimaryReplicasIds(nodeId);
        for (String clientId : remotePrimaryReplicas) {
            //get the partitions of each client
            ClusterPartition[] clientPartitions = metadataProperties.getNodePartitions().get(clientId);
            for (ClusterPartition partition : clientPartitions) {
                localResourceRepository.addInactivePartition(partition.getPartitionId());
            }
        }
        //initialize replication channel
        replicationChannel = new ReplicationChannel(nodeId, replicationProperties, txnSubsystem.getLogManager(), replicaResourcesManager, replicationManager, getServiceContext(), asterixAppRuntimeContextProvider);
        remoteRecoveryManager = new RemoteRecoveryManager(replicationManager, this, replicationProperties);
        bufferCache = new BufferCache(ioManager, prs, pcp, fileMapManager, storageProperties.getBufferCacheMaxOpenFiles(), getServiceContext().getThreadFactory(), replicationManager);
    } else {
        bufferCache = new BufferCache(ioManager, prs, pcp, fileMapManager, storageProperties.getBufferCacheMaxOpenFiles(), getServiceContext().getThreadFactory());
    }
    /*
         * The order of registration is important. The buffer cache must registered before recovery and transaction
         * managers. Notes: registered components are stopped in reversed order
         */
    ILifeCycleComponentManager lccm = getServiceContext().getLifeCycleComponentManager();
    lccm.register((ILifeCycleComponent) bufferCache);
    /*
         * LogManager must be stopped after RecoveryManager, DatasetLifeCycleManager, and ReplicationManager
         * to process any logs that might be generated during stopping these components
         */
    lccm.register((ILifeCycleComponent) txnSubsystem.getLogManager());
    /*
         * ReplicationManager must be stopped after indexLifecycleManager and recovery manager
         * so that any logs/files generated during closing datasets or checkpoints are sent to remote replicas
         */
    if (replicationManager != null) {
        lccm.register(replicationManager);
    }
    lccm.register((ILifeCycleComponent) txnSubsystem.getRecoveryManager());
    /*
         * Stopping indexLifecycleManager will flush and close all datasets.
         */
    lccm.register((ILifeCycleComponent) datasetLifecycleManager);
    lccm.register((ILifeCycleComponent) txnSubsystem.getTransactionManager());
    lccm.register((ILifeCycleComponent) txnSubsystem.getLockManager());
    lccm.register(txnSubsystem.getCheckpointManager());
}
Also used : SystemState(org.apache.asterix.common.transactions.IRecoveryManager.SystemState) IDatasetLifecycleManager(org.apache.asterix.common.api.IDatasetLifecycleManager) DatasetLifecycleManager(org.apache.asterix.common.context.DatasetLifecycleManager) ReplicaResourcesManager(org.apache.asterix.replication.storage.ReplicaResourcesManager) IReplicaResourcesManager(org.apache.asterix.common.replication.IReplicaResourcesManager) ILocalResourceRepositoryFactory(org.apache.hyracks.storage.common.file.ILocalResourceRepositoryFactory) AppRuntimeContextProviderForRecovery(org.apache.asterix.api.common.AppRuntimeContextProviderForRecovery) ThreadExecutor(org.apache.asterix.common.api.ThreadExecutor) IAppRuntimeContextProvider(org.apache.asterix.common.transactions.IAppRuntimeContextProvider) IRemoteRecoveryManager(org.apache.asterix.common.replication.IRemoteRecoveryManager) RemoteRecoveryManager(org.apache.asterix.replication.recovery.RemoteRecoveryManager) IReplicationManager(org.apache.asterix.common.replication.IReplicationManager) ReplicationManager(org.apache.asterix.replication.management.ReplicationManager) ITransactionSubsystem(org.apache.asterix.common.transactions.ITransactionSubsystem) ILifeCycleComponentManager(org.apache.hyracks.api.lifecycle.ILifeCycleComponentManager) PersistentLocalResourceRepositoryFactory(org.apache.asterix.transaction.management.resource.PersistentLocalResourceRepositoryFactory) IPageCleanerPolicy(org.apache.hyracks.storage.common.buffercache.IPageCleanerPolicy) IRecoveryManager(org.apache.asterix.common.transactions.IRecoveryManager) ReplicationChannel(org.apache.asterix.replication.management.ReplicationChannel) IReplicationChannel(org.apache.asterix.common.replication.IReplicationChannel) HeapBufferAllocator(org.apache.hyracks.storage.common.buffercache.HeapBufferAllocator) FileMapManager(org.apache.asterix.common.context.FileMapManager) IFileMapManager(org.apache.hyracks.storage.common.file.IFileMapManager) PrefixMergePolicyFactory(org.apache.hyracks.storage.am.lsm.common.impls.PrefixMergePolicyFactory) DelayPageCleanerPolicy(org.apache.hyracks.storage.common.buffercache.DelayPageCleanerPolicy) ICacheMemoryAllocator(org.apache.hyracks.storage.common.buffercache.ICacheMemoryAllocator) ActiveManager(org.apache.asterix.active.ActiveManager) IBufferCache(org.apache.hyracks.storage.common.buffercache.IBufferCache) BufferCache(org.apache.hyracks.storage.common.buffercache.BufferCache) IPageReplacementStrategy(org.apache.hyracks.storage.common.buffercache.IPageReplacementStrategy) ClockPageReplacementStrategy(org.apache.hyracks.storage.common.buffercache.ClockPageReplacementStrategy) ClusterPartition(org.apache.asterix.common.cluster.ClusterPartition)

Example 3 with IRecoveryManager

use of org.apache.asterix.common.transactions.IRecoveryManager in project asterixdb by apache.

the class CheckpointingTest method testDeleteOldLogFiles.

@Test
public void testDeleteOldLogFiles() {
    try {
        TestNodeController nc = new TestNodeController(new File(TEST_CONFIG_FILE_PATH).getAbsolutePath(), false);
        StorageComponentProvider storageManager = new StorageComponentProvider();
        nc.init();
        List<List<String>> partitioningKeys = new ArrayList<>();
        partitioningKeys.add(Collections.singletonList("key"));
        Dataset dataset = new Dataset(DATAVERSE_NAME, DATASET_NAME, DATAVERSE_NAME, DATA_TYPE_NAME, NODE_GROUP_NAME, null, null, new InternalDatasetDetails(null, PartitioningStrategy.HASH, partitioningKeys, null, null, null, false, null, false), null, DatasetType.INTERNAL, DATASET_ID, 0);
        try {
            nc.createPrimaryIndex(dataset, KEY_TYPES, RECORD_TYPE, META_TYPE, new NoMergePolicyFactory(), null, null, storageManager, KEY_INDEXES, KEY_INDICATOR_LIST);
            IHyracksTaskContext ctx = nc.createTestContext(false);
            nc.newJobId();
            ITransactionContext txnCtx = nc.getTransactionManager().getTransactionContext(nc.getTxnJobId(), true);
            // Prepare insert operation
            LSMInsertDeleteOperatorNodePushable insertOp = nc.getInsertPipeline(ctx, dataset, KEY_TYPES, RECORD_TYPE, META_TYPE, new NoMergePolicyFactory(), null, null, KEY_INDEXES, KEY_INDICATOR_LIST, storageManager).getLeft();
            insertOp.open();
            TupleGenerator tupleGenerator = new TupleGenerator(RECORD_TYPE, META_TYPE, KEY_INDEXES, KEY_INDICATOR, RECORD_GEN_FUNCTION, UNIQUE_RECORD_FIELDS, META_GEN_FUNCTION, UNIQUE_META_FIELDS);
            VSizeFrame frame = new VSizeFrame(ctx);
            FrameTupleAppender tupleAppender = new FrameTupleAppender(frame);
            IRecoveryManager recoveryManager = nc.getTransactionSubsystem().getRecoveryManager();
            ICheckpointManager checkpointManager = nc.getTransactionSubsystem().getCheckpointManager();
            LogManager logManager = (LogManager) nc.getTransactionSubsystem().getLogManager();
            // Number of log files after node startup should be one
            int numberOfLogFiles = logManager.getLogFileIds().size();
            Assert.assertEquals(1, numberOfLogFiles);
            // Low-water mark LSN
            long lowWaterMarkLSN = recoveryManager.getMinFirstLSN();
            // Low-water mark log file id
            long initialLowWaterMarkFileId = logManager.getLogFileId(lowWaterMarkLSN);
            // Initial Low-water mark should be in the only available log file
            Assert.assertEquals(initialLowWaterMarkFileId, logManager.getLogFileIds().get(0).longValue());
            // Insert records until a new log file is created
            while (logManager.getLogFileIds().size() == 1) {
                ITupleReference tuple = tupleGenerator.next();
                DataflowUtils.addTupleToFrame(tupleAppender, tuple, insertOp);
            }
            // Check if the new low-water mark is still in the initial low-water mark log file
            lowWaterMarkLSN = recoveryManager.getMinFirstLSN();
            long currentLowWaterMarkLogFileId = logManager.getLogFileId(lowWaterMarkLSN);
            if (currentLowWaterMarkLogFileId == initialLowWaterMarkFileId) {
                /*
                     * Make sure checkpoint will not delete the initial log file since
                     * the low-water mark is still in it (i.e. it is still required for
                     * recovery)
                     */
                int numberOfLogFilesBeforeCheckpoint = logManager.getLogFileIds().size();
                checkpointManager.tryCheckpoint(logManager.getAppendLSN());
                int numberOfLogFilesAfterCheckpoint = logManager.getLogFileIds().size();
                Assert.assertEquals(numberOfLogFilesBeforeCheckpoint, numberOfLogFilesAfterCheckpoint);
                /*
                     * Insert records until the low-water mark is not in the initialLowWaterMarkFileId
                     * either because of the asynchronous flush caused by the previous checkpoint or a flush
                     * due to the dataset memory budget getting full.
                     */
                while (currentLowWaterMarkLogFileId == initialLowWaterMarkFileId) {
                    ITupleReference tuple = tupleGenerator.next();
                    DataflowUtils.addTupleToFrame(tupleAppender, tuple, insertOp);
                    lowWaterMarkLSN = recoveryManager.getMinFirstLSN();
                    currentLowWaterMarkLogFileId = logManager.getLogFileId(lowWaterMarkLSN);
                }
            }
            /*
                 * At this point, the low-water mark is not in the initialLowWaterMarkFileId, so
                 * a checkpoint should delete it.
                 */
            checkpointManager.tryCheckpoint(recoveryManager.getMinFirstLSN());
            // Validate initialLowWaterMarkFileId was deleted
            for (Long fileId : logManager.getLogFileIds()) {
                Assert.assertNotEquals(initialLowWaterMarkFileId, fileId.longValue());
            }
            if (tupleAppender.getTupleCount() > 0) {
                tupleAppender.write(insertOp, true);
            }
            insertOp.close();
            nc.getTransactionManager().completedTransaction(txnCtx, DatasetId.NULL, -1, true);
        } finally {
            nc.deInit();
        }
    } catch (Throwable e) {
        e.printStackTrace();
        Assert.fail(e.getMessage());
    }
}
Also used : LSMInsertDeleteOperatorNodePushable(org.apache.asterix.common.dataflow.LSMInsertDeleteOperatorNodePushable) ICheckpointManager(org.apache.asterix.common.transactions.ICheckpointManager) Dataset(org.apache.asterix.metadata.entities.Dataset) InternalDatasetDetails(org.apache.asterix.metadata.entities.InternalDatasetDetails) ITransactionContext(org.apache.asterix.common.transactions.ITransactionContext) ArrayList(java.util.ArrayList) TupleGenerator(org.apache.asterix.app.data.gen.TupleGenerator) StorageComponentProvider(org.apache.asterix.file.StorageComponentProvider) VSizeFrame(org.apache.hyracks.api.comm.VSizeFrame) NoMergePolicyFactory(org.apache.hyracks.storage.am.lsm.common.impls.NoMergePolicyFactory) IRecoveryManager(org.apache.asterix.common.transactions.IRecoveryManager) IHyracksTaskContext(org.apache.hyracks.api.context.IHyracksTaskContext) TestNodeController(org.apache.asterix.app.bootstrap.TestNodeController) FrameTupleAppender(org.apache.hyracks.dataflow.common.comm.io.FrameTupleAppender) ITupleReference(org.apache.hyracks.dataflow.common.data.accessors.ITupleReference) ArrayList(java.util.ArrayList) List(java.util.List) File(java.io.File) LogManager(org.apache.asterix.transaction.management.service.logging.LogManager) Test(org.junit.Test)

Example 4 with IRecoveryManager

use of org.apache.asterix.common.transactions.IRecoveryManager in project asterixdb by apache.

the class RemoteRecoveryManager method replayReplicaPartitionLogs.

@Override
public void replayReplicaPartitionLogs(Set<Integer> partitions, boolean flush) throws HyracksDataException {
    ILogManager logManager = runtimeContext.getTransactionSubsystem().getLogManager();
    long minLSN = runtimeContext.getReplicaResourcesManager().getPartitionsMinLSN(partitions);
    long readableSmallestLSN = logManager.getReadableSmallestLSN();
    if (minLSN < readableSmallestLSN) {
        minLSN = readableSmallestLSN;
    }
    //replay logs > minLSN that belong to these partitions
    IRecoveryManager recoveryManager = runtimeContext.getTransactionSubsystem().getRecoveryManager();
    try {
        recoveryManager.replayPartitionsLogs(partitions, logManager.getLogReader(true), minLSN);
        if (flush) {
            runtimeContext.getDatasetLifecycleManager().flushAllDatasets();
        }
    } catch (IOException | ACIDException e) {
        throw new HyracksDataException(e);
    }
}
Also used : ILogManager(org.apache.asterix.common.transactions.ILogManager) IOException(java.io.IOException) HyracksDataException(org.apache.hyracks.api.exceptions.HyracksDataException) IRecoveryManager(org.apache.asterix.common.transactions.IRecoveryManager) ACIDException(org.apache.asterix.common.exceptions.ACIDException)

Aggregations

IRecoveryManager (org.apache.asterix.common.transactions.IRecoveryManager)4 File (java.io.File)1 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 ActiveManager (org.apache.asterix.active.ActiveManager)1 AppRuntimeContextProviderForRecovery (org.apache.asterix.api.common.AppRuntimeContextProviderForRecovery)1 TestNodeController (org.apache.asterix.app.bootstrap.TestNodeController)1 TupleGenerator (org.apache.asterix.app.data.gen.TupleGenerator)1 NCAppRuntimeContext (org.apache.asterix.app.nc.NCAppRuntimeContext)1 AsterixThreadFactory (org.apache.asterix.common.api.AsterixThreadFactory)1 IDatasetLifecycleManager (org.apache.asterix.common.api.IDatasetLifecycleManager)1 ThreadExecutor (org.apache.asterix.common.api.ThreadExecutor)1 ClusterPartition (org.apache.asterix.common.cluster.ClusterPartition)1 MessagingProperties (org.apache.asterix.common.config.MessagingProperties)1 MetadataProperties (org.apache.asterix.common.config.MetadataProperties)1 DatasetLifecycleManager (org.apache.asterix.common.context.DatasetLifecycleManager)1 FileMapManager (org.apache.asterix.common.context.FileMapManager)1 LSMInsertDeleteOperatorNodePushable (org.apache.asterix.common.dataflow.LSMInsertDeleteOperatorNodePushable)1 ACIDException (org.apache.asterix.common.exceptions.ACIDException)1