Search in sources :

Example 1 with UnderlyingStorageException

use of org.neo4j.exceptions.UnderlyingStorageException in project neo4j by neo4j.

the class CheckPointSchedulerTest method shouldCausePanicAfterSomeFailures.

@Test
void shouldCausePanicAfterSomeFailures() throws Throwable {
    // GIVEN
    RuntimeException[] failures = new RuntimeException[] { new RuntimeException("First"), new RuntimeException("Second"), new RuntimeException("Third") };
    when(checkPointer.checkPointIfNeeded(any(TriggerInfo.class))).thenThrow(failures);
    CheckPointScheduler scheduler = new CheckPointScheduler(checkPointer, ioController, jobScheduler, 1, health, "test db");
    scheduler.start();
    // WHEN
    for (int i = 0; i < CheckPointScheduler.MAX_CONSECUTIVE_FAILURES_TOLERANCE - 1; i++) {
        jobScheduler.runJob();
        verifyNoInteractions(health);
    }
    UnderlyingStorageException error = assertThrows(UnderlyingStorageException.class, jobScheduler::runJob);
    // THEN
    assertEquals(Iterators.asSet(failures), Iterators.asSet(error.getSuppressed()));
    verify(health).panic(error);
}
Also used : UnderlyingStorageException(org.neo4j.exceptions.UnderlyingStorageException) Test(org.junit.jupiter.api.Test)

Example 2 with UnderlyingStorageException

use of org.neo4j.exceptions.UnderlyingStorageException in project neo4j by neo4j.

the class NeoStores method verifyRecordFormat.

private void verifyRecordFormat(StoreType[] storeTypes, CursorContext cursorContext) {
    String expectedStoreVersion = recordFormats.storeVersion();
    long existingFormat;
    if (!fileSystem.fileExists(layout.metadataStore())) {
        // If the meta data store doesn't even exist then look no further, there's nothing to verify
        return;
    }
    if (contains(storeTypes, StoreType.META_DATA)) {
        // We're going to open this store anyway so might as well do it here, like we open the others
        MetaDataStore metaDataStore = (MetaDataStore) getOrOpenStore(StoreType.META_DATA, cursorContext);
        existingFormat = metaDataStore.getRecord(STORE_VERSION.id(), metaDataStore.newRecord(), RecordLoad.CHECK, cursorContext).getValue();
    } else {
        // if we have createIfNotExists set, but don't have the meta data store in the list of stores to open
        try {
            existingFormat = MetaDataStore.getRecord(pageCache, layout.metadataStore(), STORE_VERSION, layout.getDatabaseName(), cursorContext);
        } catch (NoSuchFileException e) {
            // Weird that the file isn't here after we passed the exists check above. Regardless, treat this the same way as above.
            return;
        } catch (IOException e) {
            throw new UnderlyingStorageException(e);
        }
    }
    if (existingFormat != MetaDataRecordFormat.FIELD_NOT_PRESENT) {
        String actualStoreVersion = versionLongToString(existingFormat);
        RecordFormats actualStoreFormat = RecordFormatSelector.selectForVersion(actualStoreVersion);
        if (!isCompatibleFormats(actualStoreFormat)) {
            throw new UnexpectedStoreVersionException(actualStoreVersion, expectedStoreVersion);
        }
    }
}
Also used : RecordFormats(org.neo4j.kernel.impl.store.format.RecordFormats) NoSuchFileException(java.nio.file.NoSuchFileException) MetaDataStore.versionLongToString(org.neo4j.kernel.impl.store.MetaDataStore.versionLongToString) IOException(java.io.IOException) UnderlyingStorageException(org.neo4j.exceptions.UnderlyingStorageException)

Example 3 with UnderlyingStorageException

use of org.neo4j.exceptions.UnderlyingStorageException in project neo4j by neo4j.

the class CommonAbstractStore method checkAndLoadStorage.

/**
 * This method is called by constructors. Checks the header record and loads the store.
 * <p>
 * Note: This method will map the file with the page cache. The store file must not
 * be accessed directly until it has been unmapped - the store file must only be
 * accessed through the page cache.
 * @param createIfNotExists If true, creates and initialises the store file if it does not exist already. If false,
 * this method will instead throw an exception in that situation.
 * @return {@code true} if the store was created as part of this call, otherwise {@code false} if it already existed.
 */
private boolean checkAndLoadStorage(boolean createIfNotExists, CursorContext cursorContext) {
    try {
        determineRecordSize(storeHeaderFormat.generateHeader());
        if (getNumberOfReservedLowIds() > 0) {
            // This store has a store-specific header so we have read it before we can be sure that we can map it with correct page size.
            // Try to open the store file (w/o creating if it doesn't exist), with page size for the configured header value.
            HEADER defaultHeader = storeHeaderFormat.generateHeader();
            pagedFile = pageCache.map(storageFile, filePageSize, databaseName, openOptions.newWith(ANY_PAGE_SIZE));
            HEADER readHeader = readStoreHeaderAndDetermineRecordSize(pagedFile, cursorContext);
            if (!defaultHeader.equals(readHeader)) {
                // The header that we read was different from the default one so unmap
                pagedFile.close();
                pagedFile = null;
            }
        }
        if (pagedFile == null) {
            // Map the file with the correct page size
            pagedFile = pageCache.map(storageFile, filePageSize, databaseName, openOptions);
        }
    } catch (NoSuchFileException | StoreNotFoundException e) {
        if (pagedFile != null) {
            pagedFile.close();
            pagedFile = null;
        }
        if (createIfNotExists) {
            try {
                // Generate the header and determine correct page size
                determineRecordSize(storeHeaderFormat.generateHeader());
                // Create the id generator, and also open it because some stores may need the id generator when initializing their store
                idGenerator = idGeneratorFactory.create(pageCache, idFile, idType, getNumberOfReservedLowIds(), false, recordFormat.getMaxId(), readOnlyChecker, configuration, cursorContext, openOptions);
                // Map the file (w/ the CREATE flag) and initialize the header
                pagedFile = pageCache.map(storageFile, filePageSize, databaseName, openOptions.newWith(CREATE));
                initialiseNewStoreFile(cursorContext);
                // <-- successfully created and initialized
                return true;
            } catch (IOException e1) {
                e.addSuppressed(e1);
            }
        }
        if (e instanceof StoreNotFoundException) {
            throw (StoreNotFoundException) e;
        }
        throw new StoreNotFoundException("Store file not found: " + storageFile, e);
    } catch (IOException e) {
        throw new UnderlyingStorageException("Unable to open store file: " + storageFile, e);
    }
    return false;
}
Also used : NoSuchFileException(java.nio.file.NoSuchFileException) IOException(java.io.IOException) UnderlyingStorageException(org.neo4j.exceptions.UnderlyingStorageException)

Example 4 with UnderlyingStorageException

use of org.neo4j.exceptions.UnderlyingStorageException in project neo4j by neo4j.

the class CommonAbstractStore method scanForHighId.

/**
 * Starts from the end of the file and scans backwards to find the highest in use record.
 * Can be used even if {@link #start(CursorContext)} hasn't been called. Basically this method should be used
 * over {@link #getHighestPossibleIdInUse(CursorContext)} and {@link #getHighId()} in cases where a store has been opened
 * but is in a scenario where recovery isn't possible, like some tooling or migration.
 *
 * @return the id of the highest in use record + 1, i.e. highId.
 */
protected long scanForHighId(CursorContext cursorContext) {
    try (PageCursor cursor = pagedFile.io(0, PF_SHARED_READ_LOCK | PF_READ_AHEAD, cursorContext)) {
        int recordsPerPage = getRecordsPerPage();
        int recordSize = getRecordSize();
        // Scan pages backwards in the chunk using page cache prefetch (PF_READ_AHEAD)
        for (long currentId = pagedFile.getLastPageId(); currentId >= 0 && cursor.next(currentId); currentId--) {
            long highestId = 0;
            boolean found;
            do {
                found = false;
                long basePageId = cursor.getCurrentPageId() * recordsPerPage;
                for (int record = 0; record < recordsPerPage; record++) {
                    cursor.setOffset(record * recordSize);
                    if (isInUse(cursor)) {
                        // We've found the highest id in use
                        highestId = basePageId + record + 1;
                        found = true;
                    }
                }
            } while (cursor.shouldRetry());
            checkIdScanCursorBounds(cursor);
            if (found) {
                return highestId;
            }
        }
        return getNumberOfReservedLowIds();
    } catch (IOException e) {
        throw new UnderlyingStorageException("Unable to find high id by scanning backwards " + getStorageFile(), e);
    }
}
Also used : IOException(java.io.IOException) UnderlyingStorageException(org.neo4j.exceptions.UnderlyingStorageException) PageCursor(org.neo4j.io.pagecache.PageCursor)

Example 5 with UnderlyingStorageException

use of org.neo4j.exceptions.UnderlyingStorageException in project neo4j by neo4j.

the class MetaDataStore method setUpgradeTransaction.

public void setUpgradeTransaction(long id, int checksum, long timestamp, CursorContext cursorContext) {
    long pageId = pageIdForRecord(Position.UPGRADE_TRANSACTION_ID.id);
    assert pageId == pageIdForRecord(Position.UPGRADE_TRANSACTION_CHECKSUM.id);
    synchronized (upgradeTransactionLock) {
        try (PageCursor cursor = pagedFile.io(pageId, PF_SHARED_WRITE_LOCK, cursorContext)) {
            if (!cursor.next()) {
                throw new UnderlyingStorageException("Could not access MetaDataStore page " + pageId);
            }
            setRecord(cursor, Position.UPGRADE_TRANSACTION_ID, id);
            setRecord(cursor, Position.UPGRADE_TRANSACTION_CHECKSUM, checksum);
            setRecord(cursor, Position.UPGRADE_TRANSACTION_COMMIT_TIMESTAMP, timestamp);
            upgradeTxIdField = id;
            upgradeTxChecksumField = checksum;
            upgradeCommitTimestampField = timestamp;
            upgradeTransaction = new TransactionId(id, checksum, timestamp);
        } catch (IOException e) {
            throw new UnderlyingStorageException(e);
        }
    }
}
Also used : IOException(java.io.IOException) UnderlyingStorageException(org.neo4j.exceptions.UnderlyingStorageException) PageCursor(org.neo4j.io.pagecache.PageCursor) TransactionId(org.neo4j.storageengine.api.TransactionId)

Aggregations

UnderlyingStorageException (org.neo4j.exceptions.UnderlyingStorageException)22 IOException (java.io.IOException)13 PageCursor (org.neo4j.io.pagecache.PageCursor)10 MetaDataRecord (org.neo4j.kernel.impl.store.record.MetaDataRecord)3 NoSuchFileException (java.nio.file.NoSuchFileException)2 Test (org.junit.jupiter.api.Test)2 PagedFile (org.neo4j.io.pagecache.PagedFile)2 LogTailInformation (org.neo4j.kernel.impl.transaction.log.files.LogTailInformation)2 TransactionId (org.neo4j.storageengine.api.TransactionId)2 UncheckedIOException (java.io.UncheckedIOException)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Map (java.util.Map)1 KernelException (org.neo4j.exceptions.KernelException)1 Pair (org.neo4j.internal.helpers.collection.Pair)1 IndexDescriptor (org.neo4j.internal.schema.IndexDescriptor)1 IndexEntryConflictException (org.neo4j.kernel.api.exceptions.index.IndexEntryConflictException)1 IndexUpdater (org.neo4j.kernel.api.index.IndexUpdater)1 MetaDataStore.versionLongToString (org.neo4j.kernel.impl.store.MetaDataStore.versionLongToString)1 MultipleUnderlyingStorageExceptions (org.neo4j.kernel.impl.store.MultipleUnderlyingStorageExceptions)1