/** * That is internal method which is called once we encounter any error inside of JVM. In such case we need to restart JVM to avoid * any data corruption. Till JVM is not restarted storage will be put in read-only state. */ public final void handleJVMError(final Error e) { if (jvmError.compareAndSet(null, e)) { OLogManager.instance().errorNoDb(this, "JVM error was thrown", e); } }
@Override public Long call() { if (flushError != null) { OLogManager.instance() .errorNoDb(this, "Can not calculate minimum LSN because of issue during data write, %s", null, flushError.getMessage()); return null; } convertSharedDirtyPagesToLocal(); if (localDirtyPagesBySegment.isEmpty()) { return null; } return localDirtyPagesBySegment.firstKey(); } }
/** * @return Major part of OrientDB version */ public static int getVersionMajor() { final String[] versions = properties.getProperty("version").split("\\."); if (versions.length == 0) { OLogManager.instance().errorNoDb(OConstants.class, "Can not retrieve version information for this build", null); return -1; } try { return Integer.parseInt(versions[0]); } catch (NumberFormatException nfe) { OLogManager.instance().errorNoDb(OConstants.class, "Can not retrieve major version information for this build", nfe); return -1; } }
/** * Checks whether there are not released buffers in the pool */ public void checkMemoryLeaks() { boolean detected = false; if (TRACK) { for (Map.Entry<OPointer, PointerTracker> entry : pointerMapping.entrySet()) { OLogManager.instance() .errorNoDb(this, "DIRECT-TRACK: unreleased direct memory pointer `%X` detected.", entry.getValue().allocation, System.identityHashCode(entry.getKey())); detected = true; } } assert !detected; }
/** * Checks reference queue to find direct memory leaks */ public void checkTrackedPointerLeaks() { boolean leaked = false; TrackedPointerReference reference; while ((reference = (TrackedPointerReference) trackedPointersQueue.poll()) != null) { if (trackedReferences.remove(reference)) { OLogManager.instance() .errorNoDb(this, "DIRECT-TRACK: unreleased direct memory pointer `%X` detected.", reference.stackTrace, reference.id); leaked = true; } } assert !leaked; }
/** * @return Minor part of OrientDB version */ public static int getVersionMinor() { final String[] versions = properties.getProperty("version").split("\\."); if (versions.length < 2) { OLogManager.instance().errorNoDb(OConstants.class, "Can not retrieve minor version information for this build", null); return -1; } try { return Integer.parseInt(versions[1]); } catch (NumberFormatException nfe) { OLogManager.instance().errorNoDb(OConstants.class, "Can not retrieve minor version information for this build", nfe); return -1; } }
/** * @return Hotfix part of OrientDB version */ @SuppressWarnings("unused") public static int getVersionHotfix() { final String[] versions = properties.getProperty("version").split("\\."); if (versions.length < 3) { return 0; } try { String hotfix = versions[2]; int snapshotIndex = hotfix.indexOf("-SNAPSHOT"); if (snapshotIndex != -1) { hotfix = hotfix.substring(0, snapshotIndex); } return Integer.parseInt(hotfix); } catch (NumberFormatException nfe) { OLogManager.instance().errorNoDb(OConstants.class, "Can not retrieve hotfix version information for this build", nfe); return -1; } }
@Override public void uncaughtException(Thread t, Throwable e) { final OLogManager logManager = OLogManager.instance(); if (logManager != null) { OLogManager.instance().errorNoDb(this, "Uncaught exception in thread %s", e, t.getName()); } } }
@Override protected void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); if (r instanceof Future<?>) { final Future<?> future = (Future<?>) r; //scheduled futures can block execution forever if they are not done if (future.isDone()) { try { future.get(); } catch (CancellationException ce) { //ignore it we cancel tasks on shutdown that is normal } catch (ExecutionException ee) { t = ee.getCause(); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); // ignore/reset } } } if (t != null) { final Thread thread = Thread.currentThread(); OLogManager.instance().errorNoDb(this, "Exception in thread '%s'", t, thread.getName()); } } }
@Override protected void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); if (r instanceof Future<?>) { final Future<?> future = (Future<?>) r; try { future.get(); } catch (CancellationException ce) { //ignore it we cancel tasks on shutdown that is normal } catch (ExecutionException ee) { t = ee.getCause(); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); // ignore/reset } } if (t != null) { final Thread thread = Thread.currentThread(); OLogManager.instance().errorNoDb(this, "Exception in thread '%s'", t, thread.getName()); } } }
private void doFlush(final boolean forceSync) { final Future<?> future = commitExecutor.submit(new RecordsWriter(forceSync, true, false)); try { future.get(); } catch (final Exception e) { OLogManager.instance().errorNoDb(this, "Exception during WAL flush", e); throw new IllegalStateException(e); } }
public Locale getLocaleInstance() { lock.acquireReadLock(); try { if (localeInstance == null) { try { localeInstance = new Locale(localeLanguage, localeCountry); } catch (RuntimeException e) { localeInstance = Locale.getDefault(); OLogManager.instance() .errorNoDb(this, "Error during initialization of locale, default one %s will be used", e, localeInstance); } } return localeInstance; } finally { lock.releaseReadLock(); } }
static OWALFile createReadWALFile(Path path, boolean allowDirectIO, int blockSize) throws IOException { if (allowDirectIO) { try { final int fd = ONative.instance().open(path.toAbsolutePath().toString(), ONative.O_RDONLY | ONative.O_DIRECT); return new OWALFdFile(fd, blockSize); } catch (LastErrorException e) { OLogManager.instance() .errorNoDb(OWALFile.class, "Can not open file using Linux API, Java FileChannel will be used instead", e); } } return new OWALChannelFile(FileChannel.open(path, StandardOpenOption.READ)); } }
static OWALFile createWriteWALFile(Path path, boolean allowDirectIO, int blockSize) throws IOException { if (allowDirectIO) { try { final int fd = ONative.instance().open(path.toAbsolutePath().toString(), ONative.O_WRONLY | ONative.O_CREAT | ONative.O_EXCL | ONative.O_APPEND | ONative.O_DIRECT); return new OWALFdFile(fd, blockSize); } catch (LastErrorException e) { OLogManager.instance() .errorNoDb(OWALFile.class, "Can not open file using Linux API, Java FileChannel will be used instead", e); } } return new OWALChannelFile( FileChannel.open(path, StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW, StandardOpenOption.APPEND)); }
@Override public Void call() throws Exception { if (flushError != null) { OLogManager.instance() .errorNoDb(this, "Can not flush data till provided segment because of issue during data write, %s", null, flushError.getMessage()); return null; } if (writeAheadLog == null) { return null; } convertSharedDirtyPagesToLocal(); Map.Entry<Long, TreeSet<PageKey>> firstEntry = localDirtyPagesBySegment.firstEntry(); if (firstEntry == null) { return null; } long minDirtySegment = firstEntry.getKey(); while (minDirtySegment < segmentId) { flushExclusivePagesIfNeeded(); flushWriteCacheFromMinLSN(writeAheadLog.begin().getSegment(), segmentId, chunkSize); firstEntry = localDirtyPagesBySegment.firstEntry(); if (firstEntry == null) { return null; } minDirtySegment = firstEntry.getKey(); } return null; }
/** * Removes direct memory pointer from container of weak references, it is done just after memory which was referenced by this * pointer will be deallocated. So no memory leaks can be caused by this pointer. */ @SuppressWarnings("ThrowableResultOfMethodCallIgnored") private void untrack(OPointer pointer) { if (TRACK) { synchronized (this) { final TrackedPointerKey trackedBufferKey = new TrackedPointerKey(pointer); final TrackedPointerReference reference = trackedBuffers.remove(trackedBufferKey); if (reference == null) { OLogManager.instance() .errorNoDb(this, "DIRECT-TRACK: untracked direct memory pointer `%X` detected.", new Exception(), id(pointer)); assert false; } else { trackedReferences.remove(reference); reference.clear(); } checkTrackedPointerLeaks(); } } }
private OLogSequenceNumber readMasterRecord(final int index) throws IOException { final long masterPosition = index * (OIntegerSerializer.INT_SIZE + 2L * OLongSerializer.LONG_SIZE); if (masterRecordLSNHolder.size() < masterPosition + MASTER_RECORD_SIZE) { OLogManager.instance().debugNoDb(this, "Cannot restore %d WAL master record for storage %s", null, index, storageName); return null; } final CRC32 crc32 = new CRC32(); try { final ByteBuffer buffer = ByteBuffer.allocate(MASTER_RECORD_SIZE); OIOUtils.readByteBuffer(buffer, masterRecordLSNHolder, masterPosition, true); buffer.rewind(); final int firstCRC = buffer.getInt(); final long segment = buffer.getLong(); final long position = buffer.getLong(); final byte[] serializedLSN = new byte[2 * OLongSerializer.LONG_SIZE]; OLongSerializer.INSTANCE.serializeLiteral(segment, serializedLSN, 0); OLongSerializer.INSTANCE.serializeLiteral(position, serializedLSN, OLongSerializer.LONG_SIZE); crc32.update(serializedLSN); if (firstCRC != ((int) crc32.getValue())) { OLogManager.instance() .errorNoDb(this, "Cannot restore %d WAL master record for storage %s crc check is failed", null, index, storageName); return null; } return new OLogSequenceNumber(segment, position); } catch (final EOFException eofException) { OLogManager.instance() .debugNoDb(this, "Cannot restore %d WAL master record for storage %s", eofException, index, storageName); return null; } }
/** * Verifies that all pointers which were allocated by allocator are freed. */ public void checkMemoryLeaks() { if (TRACK) { final long memCons = memoryConsumption.longValue(); if (memCons > 0) { OLogManager.instance() .warnNoDb(this, "DIRECT-TRACK: memory consumption is not zero (%d bytes), it may indicate presence of memory leaks", memCons); assert false; } synchronized (this) { for (TrackedPointerReference reference : trackedReferences) OLogManager.instance() .errorNoDb(this, "DIRECT-TRACK: unreleased direct memory pointer `%X` detected.", reference.stackTrace, reference.id); checkTrackedPointerLeaks(); assert trackedReferences.size() == 0; } } }
private OLogSequenceNumber restoreFromFuzzyCheckPoint(final OFuzzyCheckpointStartRecord checkPointRecord) throws IOException { OLogManager.instance().infoNoDb(this, "Data restore procedure from FUZZY checkpoint is started."); OLogSequenceNumber flushedLsn = checkPointRecord.getFlushedLsn(); if (flushedLsn.compareTo(writeAheadLog.begin()) < 0) { OLogManager.instance().errorNoDb(this, "Fuzzy checkpoint points to removed part of the log, " + "will try to restore data from the rest of the WAL", null); flushedLsn = writeAheadLog.begin(); } return restoreFrom(flushedLsn, writeAheadLog); }
@Override public Void call() { try { if (status != STATUS.OPEN) { return null; } stateLock.acquireReadLock(); try { if (status != STATUS.OPEN) { return null; } final long freezeId = atomicOperationsManager.freezeAtomicOperations(null, null); try { wal.appendSegment(segment + 1); } finally { atomicOperationsManager.releaseAtomicOperations(freezeId); } } finally { stateLock.releaseReadLock(); } } catch (Exception e) { OLogManager.instance().errorNoDb(this, "Error during addition of new segment in storage %s.", e, getName()); throw e; } return null; } }