use of org.apache.ignite.internal.processors.cache.persistence.StorageException in project ignite by apache.
the class PageMemoryImpl method tryToRestorePage.
/**
* Restores page from WAL page snapshot & delta records.
*
* @param fullId Full page ID.
* @param buf Destination byte buffer. Note: synchronization to provide ByteBuffer safety should be done outside
* this method.
*
* @throws IgniteCheckedException If failed to start WAL iteration, if incorrect page type observed in data, etc.
* @throws StorageException If it was not possible to restore page, page not found in WAL.
*/
private void tryToRestorePage(FullPageId fullId, ByteBuffer buf) throws IgniteCheckedException {
Long tmpAddr = null;
try {
ByteBuffer curPage = null;
ByteBuffer lastValidPage = null;
try (WALIterator it = walMgr.replay(null)) {
for (IgniteBiTuple<WALPointer, WALRecord> tuple : it) {
switch(tuple.getValue().type()) {
case PAGE_RECORD:
PageSnapshot snapshot = (PageSnapshot) tuple.getValue();
if (snapshot.fullPageId().equals(fullId)) {
if (tmpAddr == null) {
assert snapshot.pageDataSize() <= pageSize() : snapshot.pageDataSize();
tmpAddr = GridUnsafe.allocateMemory(pageSize());
}
if (curPage == null)
curPage = wrapPointer(tmpAddr, pageSize());
PageUtils.putBytes(tmpAddr, 0, snapshot.pageData());
if (PageIO.getCompressionType(tmpAddr) != CompressionProcessor.UNCOMPRESSED_PAGE) {
int realPageSize = realPageSize(snapshot.groupId());
assert snapshot.pageDataSize() < realPageSize : snapshot.pageDataSize();
ctx.kernalContext().compress().decompressPage(curPage, realPageSize);
}
}
break;
case CHECKPOINT_RECORD:
CheckpointRecord rec = (CheckpointRecord) tuple.getValue();
assert !rec.end();
if (curPage != null) {
lastValidPage = curPage;
curPage = null;
}
break;
case // It means that previous checkpoint was broken.
MEMORY_RECOVERY:
curPage = null;
break;
default:
if (tuple.getValue() instanceof PageDeltaRecord) {
PageDeltaRecord deltaRecord = (PageDeltaRecord) tuple.getValue();
if (curPage != null && deltaRecord.pageId() == fullId.pageId() && deltaRecord.groupId() == fullId.groupId()) {
assert tmpAddr != null;
deltaRecord.applyDelta(this, tmpAddr);
}
}
}
}
}
ByteBuffer restored = curPage == null ? lastValidPage : curPage;
if (restored == null)
throw new StorageException(String.format("Page is broken. Can't restore it from WAL. (grpId = %d, pageId = %X).", fullId.groupId(), fullId.pageId()));
buf.put(restored);
} finally {
if (tmpAddr != null)
GridUnsafe.freeMemory(tmpAddr);
}
}
use of org.apache.ignite.internal.processors.cache.persistence.StorageException in project ignite by apache.
the class PageReadWriteManagerImpl method write.
/**
* {@inheritDoc}
*/
@Override
public PageStore write(int grpId, long pageId, ByteBuffer pageBuf, int tag, boolean calculateCrc) throws IgniteCheckedException {
int partId = PageIdUtils.partId(pageId);
PageStore store = pageStores.getStore(grpId, partId);
try {
int pageSize = store.getPageSize();
int compressedPageSize = pageSize;
GridCacheContext<?, ?> cctx0 = ctx.cache().context().cacheContext(grpId);
if (cctx0 != null) {
assert pageBuf.position() == 0 && pageBuf.limit() == pageSize : pageBuf;
ByteBuffer compressedPageBuf = cctx0.compress().compressPage(pageBuf, store);
if (compressedPageBuf != pageBuf) {
compressedPageSize = PageIO.getCompressedSize(compressedPageBuf);
if (!calculateCrc) {
calculateCrc = true;
// It will be recalculated over compressed data further.
PageIO.setCrc(compressedPageBuf, 0);
}
// It is expected to be reset to 0 after each write.
PageIO.setCrc(pageBuf, 0);
pageBuf = compressedPageBuf;
}
}
store.write(pageId, pageBuf, tag, calculateCrc);
if (pageSize > compressedPageSize)
// TODO maybe add async punch mode?
store.punchHole(pageId, compressedPageSize);
} catch (StorageException e) {
ctx.failure().process(new FailureContext(FailureType.CRITICAL_ERROR, e));
throw e;
}
return store;
}
use of org.apache.ignite.internal.processors.cache.persistence.StorageException in project ignite by apache.
the class PageReadWriteManagerImpl method read.
/**
* {@inheritDoc}
*/
@Override
public void read(int grpId, long pageId, ByteBuffer pageBuf, boolean keepCrc) throws IgniteCheckedException {
PageStore store = pageStores.getStore(grpId, PageIdUtils.partId(pageId));
try {
store.read(pageId, pageBuf, keepCrc);
ctx.compress().decompressPage(pageBuf, store.getPageSize());
} catch (StorageException e) {
ctx.failure().process(new FailureContext(FailureType.CRITICAL_ERROR, e));
throw e;
}
}
use of org.apache.ignite.internal.processors.cache.persistence.StorageException in project ignite by apache.
the class FilePageStore method write.
/**
* {@inheritDoc}
*/
@Override
public void write(long pageId, ByteBuffer pageBuf, int tag, boolean calculateCrc) throws IgniteCheckedException {
init();
boolean interrupted = false;
while (true) {
FileIO fileIO = this.fileIO;
try {
lock.readLock().lock();
try {
if (tag < this.tag)
return;
long off = pageOffset(pageId);
assert (off >= 0 && off <= allocated.get()) || recover : "off=" + U.hexLong(off) + ", allocated=" + U.hexLong(allocated.get()) + ", pageId=" + U.hexLong(pageId) + ", file=" + getFileAbsolutePath();
assert pageBuf.position() == 0;
assert pageBuf.order() == ByteOrder.nativeOrder() : "Page buffer order " + pageBuf.order() + " should be same with " + ByteOrder.nativeOrder();
assert PageIO.getType(pageBuf) != 0 : "Invalid state. Type is 0! pageId = " + U.hexLong(pageId);
assert PageIO.getVersion(pageBuf) != 0 : "Invalid state. Version is 0! pageId = " + U.hexLong(pageId);
if (calculateCrc && !skipCrc) {
assert PageIO.getCrc(pageBuf) == 0 : U.hexLong(pageId);
PageIO.setCrc(pageBuf, calcCrc32(pageBuf, getCrcSize(pageId, pageBuf)));
}
// Check whether crc was calculated somewhere above the stack if it is forcibly skipped.
assert skipCrc || PageIO.getCrc(pageBuf) != 0 || calcCrc32(pageBuf, pageSize) == 0 : "CRC hasn't been calculated, crc=0";
assert pageBuf.position() == 0 : pageBuf.position();
for (PageWriteListener lsnr : lsnrs) {
lsnr.accept(pageId, pageBuf);
pageBuf.rewind();
}
fileIO.writeFully(pageBuf, off);
PageIO.setCrc(pageBuf, 0);
if (interrupted)
Thread.currentThread().interrupt();
return;
} finally {
lock.readLock().unlock();
}
} catch (IOException e) {
if (e instanceof ClosedChannelException) {
try {
if (e instanceof ClosedByInterruptException) {
interrupted = true;
Thread.interrupted();
}
reinit(fileIO);
pageBuf.position(0);
PageIO.setCrc(pageBuf, 0);
continue;
} catch (IOException e0) {
e0.addSuppressed(e);
e = e0;
}
}
throw new StorageException("Failed to write page [file=" + getFileAbsolutePath() + ", pageId=" + pageId + ", tag=" + tag + "]", e);
}
}
}
use of org.apache.ignite.internal.processors.cache.persistence.StorageException in project ignite by apache.
the class FilePageStore method finishRecover.
/**
* {@inheritDoc}
*/
@Override
public void finishRecover() throws StorageException {
lock.writeLock().lock();
try {
// Since we always have a meta-page in the store, never revert allocated counter to a value smaller than page.
if (inited) {
long newSize = Math.max(pageSize, fileIO.size() - headerSize());
// In the case of compressed pages we can miss the tail of the page.
if (newSize % pageSize != 0)
newSize += pageSize - newSize % pageSize;
long delta = newSize - allocated.getAndSet(newSize);
assert delta % pageSize == 0 : delta;
allocatedTracker.accept(delta / pageSize);
}
recover = false;
} catch (IOException e) {
throw new StorageException("Failed to finish recover partition file [file=" + getFileAbsolutePath() + "]", e);
} finally {
lock.writeLock().unlock();
}
}
Aggregations