Search in sources :

Example 1 with BlobStore

use of org.exist.storage.blob.BlobStore in project exist by eXist-db.

the class NativeBroker method storeBinaryResource.

@Override
public void storeBinaryResource(final Txn transaction, final BinaryDocument blob, final InputStream is) throws IOException {
    final BlobStore blobStore = pool.getBlobStore();
    final Tuple2<BlobId, Long> blobIdLen = blobStore.add(transaction, is);
    blob.setBlobId(blobIdLen._1);
    blob.setContentLength(blobIdLen._2);
}
Also used : BlobId(org.exist.storage.blob.BlobId) BlobStore(org.exist.storage.blob.BlobStore)

Example 2 with BlobStore

use of org.exist.storage.blob.BlobStore in project exist by eXist-db.

the class NativeBroker method copyBinaryResource.

private void copyBinaryResource(final Txn transaction, final BinaryDocument srcDoc, final BinaryDocument dstDoc) throws IOException {
    final BlobStore blobStore = pool.getBlobStore();
    final BlobId dstBlobId = blobStore.copy(transaction, srcDoc.getBlobId());
    dstDoc.setBlobId(dstBlobId);
    dstDoc.setContentLength(srcDoc.getContentLength());
}
Also used : BlobId(org.exist.storage.blob.BlobId) BlobStore(org.exist.storage.blob.BlobStore)

Example 3 with BlobStore

use of org.exist.storage.blob.BlobStore in project exist by eXist-db.

the class MetadataFunctions method extractMetadataFromLocalResource.

private Sequence extractMetadataFromLocalResource(final XmldbURI docUri) throws XPathException {
    try (final LockedDocument lockedDoc = context.getBroker().getXMLResource(docUri, LockMode.READ_LOCK)) {
        if (lockedDoc != null && lockedDoc.getDocument() instanceof BinaryDocument) {
            final BinaryDocument binDoc = (BinaryDocument) lockedDoc.getDocument();
            final BrokerPool pool = context.getBroker().getBrokerPool();
            final BlobStore blobStore = pool.getBlobStore();
            try (final Txn transaction = pool.getTransactionManager().beginTransaction()) {
                final Sequence result = blobStore.with(transaction, binDoc.getBlobId(), blobFile -> TaggedTryUnchecked(XPathException.class, () -> exifToolExtract(blobFile))).get();
                transaction.commit();
                return result;
            }
        } else {
            throw new XPathException(this, "The binary document at " + docUri.toString() + " cannot be found.");
        }
    } catch (PermissionDeniedException | IOException | TransactionException e) {
        throw new XPathException(this, "Could not access binary document: " + e.getMessage(), e);
    }
}
Also used : BinaryDocument(org.exist.dom.persistent.BinaryDocument) LockMode(org.exist.storage.lock.Lock.LockMode) Txn(org.exist.storage.txn.Txn) BrokerPool(org.exist.storage.BrokerPool) SequenceType(org.exist.xquery.value.SequenceType) FunctionParameterSequenceType(org.exist.xquery.value.FunctionParameterSequenceType) QName(org.exist.dom.QName) URISyntaxException(java.net.URISyntaxException) FunctionSignature(org.exist.xquery.FunctionSignature) PermissionDeniedException(org.exist.security.PermissionDeniedException) Cardinality(org.exist.xquery.Cardinality) BlobStore(org.exist.storage.blob.BlobStore) BasicFunction(org.exist.xquery.BasicFunction) UnsynchronizedByteArrayOutputStream(org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream) Source(org.exist.source.Source) FunctionReturnSequenceType(org.exist.xquery.value.FunctionReturnSequenceType) XmldbURI(org.exist.xmldb.XmldbURI) URI(java.net.URI) Path(java.nio.file.Path) XQueryContext(org.exist.xquery.XQueryContext) OutputStream(java.io.OutputStream) InputSource(org.xml.sax.InputSource) LockedDocument(org.exist.dom.persistent.LockedDocument) Type(org.exist.xquery.value.Type) IOException(java.io.IOException) TransactionException(org.exist.storage.txn.TransactionException) Logger(org.apache.logging.log4j.Logger) TaggedTryUnchecked(com.evolvedbinary.j8fu.Try.TaggedTryUnchecked) ModuleUtils(org.exist.xquery.modules.ModuleUtils) SAXException(org.xml.sax.SAXException) SourceFactory(org.exist.source.SourceFactory) Sequence(org.exist.xquery.value.Sequence) LogManager(org.apache.logging.log4j.LogManager) BinaryDocument(org.exist.dom.persistent.BinaryDocument) XPathException(org.exist.xquery.XPathException) InputStream(java.io.InputStream) TransactionException(org.exist.storage.txn.TransactionException) XPathException(org.exist.xquery.XPathException) LockedDocument(org.exist.dom.persistent.LockedDocument) PermissionDeniedException(org.exist.security.PermissionDeniedException) Txn(org.exist.storage.txn.Txn) Sequence(org.exist.xquery.value.Sequence) IOException(java.io.IOException) BrokerPool(org.exist.storage.BrokerPool) BlobStore(org.exist.storage.blob.BlobStore)

Example 4 with BlobStore

use of org.exist.storage.blob.BlobStore in project exist by eXist-db.

the class RecoveryManager method recover.

/**
 * Checks if the database is in a consistent state. If not, start a recovery run.
 *
 * The method scans the last log file and tries to find the last checkpoint
 * record. If the checkpoint record is the last record in the file,
 * the database was closed cleanly and is in a consistent state. If not, a
 * recovery run is started beginning at the last checkpoint found.
 *
 * @throws LogException Reading of journal failed.
 * @return if recover was successful
 */
public boolean recover() throws LogException {
    boolean recoveryRun = false;
    final List<Path> files;
    try (final Stream<Path> fileStream = journalRecovery.getFiles.get()) {
        files = fileStream.collect(Collectors.toList());
    } catch (final IOException ioe) {
        throw new LogException("Unable to find journal files in data dir", ioe);
    }
    // find the last log file in the data directory
    final short lastNum = Journal.findLastFile(files.stream());
    if (-1 < lastNum) {
        // load the last log file
        final Path last = journalRecovery.getFile.apply(lastNum);
        // scan the last log file and record the last checkpoint found
        try (JournalReader reader = new JournalReader(broker, last, lastNum)) {
            // try to read the last log record to see if it is a checkpoint
            boolean checkpointFound = false;
            try {
                final Loggable lastLog = reader.lastEntry();
                if (lastLog != null && lastLog.getLogType() == LogEntryTypes.CHECKPOINT) {
                    final Checkpoint checkpoint = (Checkpoint) lastLog;
                    // record, we compare the LSN stored in it with the current LSN.
                    if (checkpoint.getStoredLsn().equals(checkpoint.getLsn())) {
                        checkpointFound = true;
                        LOG.debug("Database is in clean state. Last checkpoint: {}", checkpoint.getDateString());
                    }
                }
            } catch (final LogException e) {
                LOG.info("Reading last journal log entry failed: {}. Will scan the log...", e.getMessage());
                // if an exception occurs at this point, the journal file is probably incomplete,
                // which indicates a db crash
                checkpointFound = false;
            }
            if (!checkpointFound) {
                LOG.info("Unclean shutdown detected. Scanning journal...");
                broker.getBrokerPool().reportStatus("Unclean shutdown detected. Scanning log...");
                reader.positionFirst();
                final Long2ObjectMap<Loggable> txnsStarted = new Long2ObjectOpenHashMap<>();
                Checkpoint lastCheckpoint = null;
                Lsn lastLsn = Lsn.LSN_INVALID;
                Loggable next;
                try {
                    final ProgressBar progress = new ProgressBar("Scanning journal ", FileUtils.sizeQuietly(last));
                    while ((next = reader.nextEntry()) != null) {
                        // LOG.debug(next.dump());
                        progress.set(next.getLsn().getOffset());
                        if (next.getLogType() == LogEntryTypes.TXN_START) {
                            // new transaction starts: add it to the transactions table
                            txnsStarted.put(next.getTransactionId(), next);
                        } else if (next.getLogType() == LogEntryTypes.TXN_ABORT) {
                            // transaction aborted: remove it from the transactions table
                            txnsStarted.remove(next.getTransactionId());
                        } else if (next.getLogType() == LogEntryTypes.CHECKPOINT) {
                            txnsStarted.clear();
                            lastCheckpoint = (Checkpoint) next;
                        }
                        lastLsn = next.getLsn();
                    }
                } catch (final LogException e) {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Caught exception while reading log", e);
                    }
                    LOG.warn("Last readable journal log entry lsn: {}", lastLsn);
                }
                // we need a recovery.
                if ((lastCheckpoint == null || !lastCheckpoint.getLsn().equals(lastLsn)) && txnsStarted.size() > 0) {
                    LOG.info("Dirty transactions: {}", txnsStarted.size());
                    // starting recovery: reposition the log reader to the last checkpoint
                    if (lastCheckpoint == null) {
                        reader.positionFirst();
                    } else {
                        reader.position(lastCheckpoint.getLsn());
                        next = reader.nextEntry();
                    }
                    recoveryRun = true;
                    try {
                        LOG.info("Running recovery...");
                        broker.getBrokerPool().reportStatus("Running recovery...");
                        try (final BlobStore blobStore = broker.getBrokerPool().getBlobStore()) {
                            try {
                                blobStore.openForRecovery();
                            } catch (final FileNotFoundException e) {
                                LOG.warn(e.getMessage(), e);
                            } catch (final IOException e) {
                                throw new LogException("Unable to Open the Blob Store for Recovery: " + e.getMessage(), e);
                            }
                            doRecovery(txnsStarted.size(), last, reader, lastLsn);
                        } catch (final IOException e) {
                            LOG.error("Error whilst closing the Blob Store after recovery: {}", e.getMessage(), e);
                        }
                    } catch (final LogException e) {
                        // if restartOnError == true, we try to bring up the database even if there
                        // are errors. Otherwise, an exception is thrown, which will stop the db initialization
                        broker.getBrokerPool().reportStatus(BrokerPool.SIGNAL_ABORTED);
                        if (restartOnError) {
                            LOG.error("Aborting recovery. eXist-db detected an error during recovery. This may not be fatal. Database will start up, but corruptions are likely.");
                        } else {
                            LOG.error("Aborting recovery. eXist-db detected an error during recovery. This may not be fatal. Please consider running a consistency check via the export tool and create a backup if problems are reported. The db should come up again if you restart it.");
                            throw e;
                        }
                    }
                } else {
                    LOG.info("Database is in clean state. Nothing to recover from the journal.");
                }
            }
        } finally {
            // remove .log files from directory even if recovery failed.
            // Re-applying them on a second start up attempt would definitely damage the db, so we better
            // delete them before user tries to launch again.
            cleanDirectory(files.stream());
            if (recoveryRun) {
                broker.repairPrimary();
                broker.sync(Sync.MAJOR);
            }
        }
    }
    journalRecovery.setCurrentFileNum.accept(lastNum);
    journalRecovery.switchFiles.get();
    return recoveryRun;
}
Also used : Path(java.nio.file.Path) FileNotFoundException(java.io.FileNotFoundException) IOException(java.io.IOException) Long2ObjectOpenHashMap(it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap) Checkpoint(org.exist.storage.txn.Checkpoint) ProgressBar(org.exist.util.ProgressBar) BlobStore(org.exist.storage.blob.BlobStore)

Example 5 with BlobStore

use of org.exist.storage.blob.BlobStore in project exist by eXist-db.

the class NativeBroker method removeBinaryResource.

@Override
public void removeBinaryResource(final Txn transaction, final BinaryDocument blob) throws PermissionDeniedException, IOException {
    if (isReadOnly()) {
        throw new IOException(DATABASE_IS_READ_ONLY);
    }
    if (LOG.isDebugEnabled()) {
        LOG.debug("removing binary resource {}...", blob.getDocId());
    }
    if (blob.getBlobId() == null) {
        LOG.warn("Trying to delete binary document: {}, but blobId was null", blob.getURI());
        return;
    }
    final BlobStore blobStore = pool.getBlobStore();
    blobStore.remove(transaction, blob.getBlobId());
    // remove the file from the database metadata and indexes
    removeResourceMetadata(transaction, blob);
    getIndexController().setDocument(blob, ReindexMode.REMOVE_BINARY);
    getIndexController().flush();
}
Also used : BlobStore(org.exist.storage.blob.BlobStore)

Aggregations

BlobStore (org.exist.storage.blob.BlobStore)7 IOException (java.io.IOException)2 Path (java.nio.file.Path)2 BlobId (org.exist.storage.blob.BlobId)2 XmldbURI (org.exist.xmldb.XmldbURI)2 TaggedTryUnchecked (com.evolvedbinary.j8fu.Try.TaggedTryUnchecked)1 Long2ObjectOpenHashMap (it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap)1 FileNotFoundException (java.io.FileNotFoundException)1 InputStream (java.io.InputStream)1 OutputStream (java.io.OutputStream)1 URI (java.net.URI)1 URISyntaxException (java.net.URISyntaxException)1 UnsynchronizedByteArrayOutputStream (org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream)1 LogManager (org.apache.logging.log4j.LogManager)1 Logger (org.apache.logging.log4j.Logger)1 QName (org.exist.dom.QName)1 BinaryDocument (org.exist.dom.persistent.BinaryDocument)1 LockedDocument (org.exist.dom.persistent.LockedDocument)1 PermissionDeniedException (org.exist.security.PermissionDeniedException)1 Source (org.exist.source.Source)1