Search in sources :

Example 6 with ILSMIndex

use of org.apache.hyracks.storage.am.lsm.common.api.ILSMIndex in project asterixdb by apache.

the class PrimaryIndexOperationTracker method flushIfRequested.

public void flushIfRequested() throws HyracksDataException {
    // If we need a flush, and this is the last completing operation, then schedule the flush,
    // or if there is a flush scheduled by the checkpoint (flushOnExit), then schedule it
    boolean needsFlush = false;
    Set<ILSMIndex> indexes = dsInfo.getDatasetIndexes();
    if (!flushOnExit) {
        for (ILSMIndex lsmIndex : indexes) {
            if (lsmIndex.hasFlushRequestForCurrentMutableComponent()) {
                needsFlush = true;
                break;
            }
        }
    }
    if (needsFlush || flushOnExit) {
        //Make the current mutable components READABLE_UNWRITABLE to stop coming modify operations from entering them until the current flush is scheduled.
        for (ILSMIndex lsmIndex : indexes) {
            ILSMOperationTracker opTracker = lsmIndex.getOperationTracker();
            synchronized (opTracker) {
                ILSMMemoryComponent memComponent = lsmIndex.getCurrentMemoryComponent();
                if (memComponent.getState() == ComponentState.READABLE_WRITABLE && memComponent.isModified()) {
                    memComponent.setState(ComponentState.READABLE_UNWRITABLE);
                }
            }
        }
        LogRecord logRecord = new LogRecord();
        flushOnExit = false;
        if (dsInfo.isDurable()) {
            /**
                 * Generate a FLUSH log.
                 * Flush will be triggered when the log is written to disk by LogFlusher.
                 */
            TransactionUtil.formFlushLogRecord(logRecord, datasetID, this, logManager.getNodeId(), dsInfo.getDatasetIndexes().size());
            try {
                logManager.log(logRecord);
            } catch (ACIDException e) {
                throw new HyracksDataException("could not write flush log", e);
            }
            flushLogCreated = true;
        } else {
            //trigger flush for temporary indexes without generating a FLUSH log.
            triggerScheduleFlush(logRecord);
        }
    }
}
Also used : LogRecord(org.apache.asterix.common.transactions.LogRecord) ILSMMemoryComponent(org.apache.hyracks.storage.am.lsm.common.api.ILSMMemoryComponent) ILSMIndex(org.apache.hyracks.storage.am.lsm.common.api.ILSMIndex) HyracksDataException(org.apache.hyracks.api.exceptions.HyracksDataException) ILSMOperationTracker(org.apache.hyracks.storage.am.lsm.common.api.ILSMOperationTracker) ACIDException(org.apache.asterix.common.exceptions.ACIDException)

Example 7 with ILSMIndex

use of org.apache.hyracks.storage.am.lsm.common.api.ILSMIndex in project asterixdb by apache.

the class PrimaryIndexOperationTracker method triggerScheduleFlush.

//This method is called sequentially by LogPage.notifyFlushTerminator in the sequence flushes were scheduled.
public synchronized void triggerScheduleFlush(LogRecord logRecord) throws HyracksDataException {
    for (ILSMIndex lsmIndex : dsInfo.getDatasetIndexes()) {
        //get resource
        ILSMIndexAccessor accessor = lsmIndex.createAccessor(NoOpOperationCallback.INSTANCE, NoOpOperationCallback.INSTANCE);
        //update resource lsn
        AbstractLSMIOOperationCallback ioOpCallback = (AbstractLSMIOOperationCallback) lsmIndex.getIOOperationCallback();
        ioOpCallback.updateLastLSN(logRecord.getLSN());
        //schedule flush after update
        accessor.scheduleFlush(lsmIndex.getIOOperationCallback());
    }
    flushLogCreated = false;
}
Also used : AbstractLSMIOOperationCallback(org.apache.asterix.common.ioopcallbacks.AbstractLSMIOOperationCallback) ILSMIndex(org.apache.hyracks.storage.am.lsm.common.api.ILSMIndex) ILSMIndexAccessor(org.apache.hyracks.storage.am.lsm.common.api.ILSMIndexAccessor)

Example 8 with ILSMIndex

use of org.apache.hyracks.storage.am.lsm.common.api.ILSMIndex in project asterixdb by apache.

the class RecoveryManager method startRecoveryRedoPhase.

private synchronized void startRecoveryRedoPhase(Set<Integer> partitions, ILogReader logReader, long lowWaterMarkLSN, Set<Integer> winnerJobSet) throws IOException, ACIDException {
    int redoCount = 0;
    int jobId = -1;
    long resourceId;
    long maxDiskLastLsn;
    long lsn = -1;
    ILSMIndex index = null;
    LocalResource localResource = null;
    DatasetLocalResource localResourceMetadata = null;
    boolean foundWinner = false;
    JobEntityCommits jobEntityWinners = null;
    IAppRuntimeContextProvider appRuntimeContext = txnSubsystem.getAsterixAppRuntimeContextProvider();
    IDatasetLifecycleManager datasetLifecycleManager = appRuntimeContext.getDatasetLifecycleManager();
    Map<Long, LocalResource> resourcesMap = localResourceRepository.loadAndGetAllResources();
    Map<Long, Long> resourceId2MaxLSNMap = new HashMap<>();
    TxnId tempKeyTxnId = new TxnId(-1, -1, -1, null, -1, false);
    ILogRecord logRecord = null;
    try {
        logReader.initializeScan(lowWaterMarkLSN);
        logRecord = logReader.next();
        while (logRecord != null) {
            if (IS_DEBUG_MODE) {
                LOGGER.info(logRecord.getLogRecordForDisplay());
            }
            lsn = logRecord.getLSN();
            jobId = logRecord.getJobId();
            foundWinner = false;
            switch(logRecord.getLogType()) {
                case LogType.UPDATE:
                    if (partitions.contains(logRecord.getResourcePartition())) {
                        if (winnerJobSet.contains(jobId)) {
                            foundWinner = true;
                        } else if (jobId2WinnerEntitiesMap.containsKey(jobId)) {
                            jobEntityWinners = jobId2WinnerEntitiesMap.get(jobId);
                            tempKeyTxnId.setTxnId(jobId, logRecord.getDatasetId(), logRecord.getPKHashValue(), logRecord.getPKValue(), logRecord.getPKValueSize());
                            if (jobEntityWinners.containsEntityCommitForTxnId(lsn, tempKeyTxnId)) {
                                foundWinner = true;
                            }
                        }
                        if (foundWinner) {
                            resourceId = logRecord.getResourceId();
                            localResource = resourcesMap.get(resourceId);
                            /*******************************************************************
                                 * [Notice]
                                 * -> Issue
                                 * Delete index may cause a problem during redo.
                                 * The index operation to be redone couldn't be redone because the corresponding index
                                 * may not exist in NC due to the possible index drop DDL operation.
                                 * -> Approach
                                 * Avoid the problem during redo.
                                 * More specifically, the problem will be detected when the localResource of
                                 * the corresponding index is retrieved, which will end up with 'null'.
                                 * If null is returned, then just go and process the next
                                 * log record.
                                 *******************************************************************/
                            if (localResource == null) {
                                LOGGER.log(Level.WARNING, "resource was not found for resource id " + resourceId);
                                logRecord = logReader.next();
                                continue;
                            }
                            /*******************************************************************/
                            //get index instance from IndexLifeCycleManager
                            //if index is not registered into IndexLifeCycleManager,
                            //create the index using LocalMetadata stored in LocalResourceRepository
                            //get partition path in this node
                            localResourceMetadata = (DatasetLocalResource) localResource.getResource();
                            index = (ILSMIndex) datasetLifecycleManager.get(localResource.getPath());
                            if (index == null) {
                                //#. create index instance and register to indexLifeCycleManager
                                index = (ILSMIndex) localResourceMetadata.createInstance(serviceCtx);
                                datasetLifecycleManager.register(localResource.getPath(), index);
                                datasetLifecycleManager.open(localResource.getPath());
                                //#. get maxDiskLastLSN
                                ILSMIndex lsmIndex = index;
                                try {
                                    maxDiskLastLsn = ((AbstractLSMIOOperationCallback) lsmIndex.getIOOperationCallback()).getComponentLSN(lsmIndex.getImmutableComponents());
                                } catch (HyracksDataException e) {
                                    datasetLifecycleManager.close(localResource.getPath());
                                    throw e;
                                }
                                //#. set resourceId and maxDiskLastLSN to the map
                                resourceId2MaxLSNMap.put(resourceId, maxDiskLastLsn);
                            } else {
                                maxDiskLastLsn = resourceId2MaxLSNMap.get(resourceId);
                            }
                            if (lsn > maxDiskLastLsn) {
                                redo(logRecord, datasetLifecycleManager);
                                redoCount++;
                            }
                        }
                    }
                    break;
                case LogType.JOB_COMMIT:
                case LogType.ENTITY_COMMIT:
                case LogType.ABORT:
                case LogType.FLUSH:
                case LogType.WAIT:
                case LogType.MARKER:
                    //do nothing
                    break;
                default:
                    throw new ACIDException("Unsupported LogType: " + logRecord.getLogType());
            }
            logRecord = logReader.next();
        }
        LOGGER.info("Logs REDO phase completed. Redo logs count: " + redoCount);
    } finally {
        //close all indexes
        Set<Long> resourceIdList = resourceId2MaxLSNMap.keySet();
        for (long r : resourceIdList) {
            datasetLifecycleManager.close(resourcesMap.get(r).getPath());
        }
    }
}
Also used : HashMap(java.util.HashMap) ILSMIndex(org.apache.hyracks.storage.am.lsm.common.api.ILSMIndex) Checkpoint(org.apache.asterix.common.transactions.Checkpoint) HyracksDataException(org.apache.hyracks.api.exceptions.HyracksDataException) DatasetLocalResource(org.apache.asterix.common.dataflow.DatasetLocalResource) LocalResource(org.apache.hyracks.storage.common.LocalResource) ACIDException(org.apache.asterix.common.exceptions.ACIDException) DatasetLocalResource(org.apache.asterix.common.dataflow.DatasetLocalResource) IDatasetLifecycleManager(org.apache.asterix.common.api.IDatasetLifecycleManager) TxnId(org.apache.asterix.transaction.management.service.recovery.TxnId) IAppRuntimeContextProvider(org.apache.asterix.common.transactions.IAppRuntimeContextProvider) ILogRecord(org.apache.asterix.common.transactions.ILogRecord)

Example 9 with ILSMIndex

use of org.apache.hyracks.storage.am.lsm.common.api.ILSMIndex in project asterixdb by apache.

the class RecoveryManager method undo.

private static void undo(ILogRecord logRecord, IDatasetLifecycleManager datasetLifecycleManager) {
    try {
        ILSMIndex index = (ILSMIndex) datasetLifecycleManager.getIndex(logRecord.getDatasetId(), logRecord.getResourceId());
        ILSMIndexAccessor indexAccessor = index.createAccessor(NoOpOperationCallback.INSTANCE, NoOpOperationCallback.INSTANCE);
        if (logRecord.getNewOp() == AbstractIndexModificationOperationCallback.INSERT_BYTE) {
            indexAccessor.forceDelete(logRecord.getNewValue());
        } else if (logRecord.getNewOp() == AbstractIndexModificationOperationCallback.DELETE_BYTE) {
            indexAccessor.forceInsert(logRecord.getOldValue());
        } else if (logRecord.getNewOp() == AbstractIndexModificationOperationCallback.UPSERT_BYTE) {
            // undo, upsert the old value if found, otherwise, physical delete
            if (logRecord.getOldValue() == null) {
                indexAccessor.forcePhysicalDelete(logRecord.getNewValue());
            } else {
                indexAccessor.forceUpsert(logRecord.getOldValue());
            }
        } else {
            throw new IllegalStateException("Unsupported OperationType: " + logRecord.getNewOp());
        }
    } catch (Exception e) {
        throw new IllegalStateException("Failed to undo", e);
    }
}
Also used : ILSMIndex(org.apache.hyracks.storage.am.lsm.common.api.ILSMIndex) ILSMIndexAccessor(org.apache.hyracks.storage.am.lsm.common.api.ILSMIndexAccessor) ACIDException(org.apache.asterix.common.exceptions.ACIDException) HyracksDataException(org.apache.hyracks.api.exceptions.HyracksDataException) IOException(java.io.IOException)

Example 10 with ILSMIndex

use of org.apache.hyracks.storage.am.lsm.common.api.ILSMIndex in project asterixdb by apache.

the class RecoveryManager method redo.

private static void redo(ILogRecord logRecord, IDatasetLifecycleManager datasetLifecycleManager) {
    try {
        int datasetId = logRecord.getDatasetId();
        long resourceId = logRecord.getResourceId();
        ILSMIndex index = (ILSMIndex) datasetLifecycleManager.getIndex(datasetId, resourceId);
        ILSMIndexAccessor indexAccessor = index.createAccessor(NoOpOperationCallback.INSTANCE, NoOpOperationCallback.INSTANCE);
        if (logRecord.getNewOp() == AbstractIndexModificationOperationCallback.INSERT_BYTE) {
            indexAccessor.forceInsert(logRecord.getNewValue());
        } else if (logRecord.getNewOp() == AbstractIndexModificationOperationCallback.DELETE_BYTE) {
            indexAccessor.forceDelete(logRecord.getNewValue());
        } else if (logRecord.getNewOp() == AbstractIndexModificationOperationCallback.UPSERT_BYTE) {
            // redo, upsert the new value
            indexAccessor.forceUpsert(logRecord.getNewValue());
        } else {
            throw new IllegalStateException("Unsupported OperationType: " + logRecord.getNewOp());
        }
    } catch (Exception e) {
        throw new IllegalStateException("Failed to redo", e);
    }
}
Also used : ILSMIndex(org.apache.hyracks.storage.am.lsm.common.api.ILSMIndex) ILSMIndexAccessor(org.apache.hyracks.storage.am.lsm.common.api.ILSMIndexAccessor) Checkpoint(org.apache.asterix.common.transactions.Checkpoint) ACIDException(org.apache.asterix.common.exceptions.ACIDException) HyracksDataException(org.apache.hyracks.api.exceptions.HyracksDataException) IOException(java.io.IOException)

Aggregations

ILSMIndex (org.apache.hyracks.storage.am.lsm.common.api.ILSMIndex)15 HyracksDataException (org.apache.hyracks.api.exceptions.HyracksDataException)11 ACIDException (org.apache.asterix.common.exceptions.ACIDException)9 ILSMIndexAccessor (org.apache.hyracks.storage.am.lsm.common.api.ILSMIndexAccessor)8 IModificationOperationCallback (org.apache.hyracks.storage.common.IModificationOperationCallback)8 ITransactionContext (org.apache.asterix.common.transactions.ITransactionContext)7 DatasetLocalResource (org.apache.asterix.common.dataflow.DatasetLocalResource)6 DatasetId (org.apache.asterix.common.transactions.DatasetId)5 ITransactionSubsystem (org.apache.asterix.common.transactions.ITransactionSubsystem)5 IResourceLifecycleManager (org.apache.hyracks.storage.common.IResourceLifecycleManager)3 IOException (java.io.IOException)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 IDatasetLifecycleManager (org.apache.asterix.common.api.IDatasetLifecycleManager)2 Checkpoint (org.apache.asterix.common.transactions.Checkpoint)2 AMutableString (org.apache.asterix.om.base.AMutableString)2 AString (org.apache.asterix.om.base.AString)2 TransactionContext (org.apache.asterix.transaction.management.service.transaction.TransactionContext)2 ILSMDiskComponent (org.apache.hyracks.storage.am.lsm.common.api.ILSMDiskComponent)2 ILSMDiskComponentId (org.apache.hyracks.storage.am.lsm.common.api.ILSMDiskComponentId)2