use of org.apache.ignite.internal.pagemem.wal.record.PageSnapshot in project ignite by apache.
the class RecordDataV1Serializer method readPlainRecord.
/**
* Reads {@code WalRecord} of {@code type} from input.
* Input should be plain(not encrypted).
*
* @param type Record type.
* @param in Input
* @param encrypted Record was encrypted.
* @param recordSize Record size.
* @return Deserialized record.
* @throws IOException If failed.
* @throws IgniteCheckedException If failed.
*/
WALRecord readPlainRecord(RecordType type, ByteBufferBackedDataInput in, boolean encrypted, int recordSize) throws IOException, IgniteCheckedException {
WALRecord res;
switch(type) {
case PAGE_RECORD:
byte[] arr = new byte[pageSize];
int cacheId = in.readInt();
long pageId = in.readLong();
in.readFully(arr);
res = new PageSnapshot(new FullPageId(pageId, cacheId), arr, encrypted ? realPageSize : pageSize);
break;
case CHECKPOINT_RECORD:
long msb = in.readLong();
long lsb = in.readLong();
boolean hasPtr = in.readByte() != 0;
long idx = hasPtr ? in.readLong() : 0;
int off = hasPtr ? in.readInt() : 0;
int len = hasPtr ? in.readInt() : 0;
Map<Integer, CacheState> states = readPartitionStates(in);
boolean end = in.readByte() != 0;
WALPointer walPtr = hasPtr ? new WALPointer(idx, off, len) : null;
CheckpointRecord cpRec = new CheckpointRecord(new UUID(msb, lsb), walPtr, end);
cpRec.cacheGroupStates(states);
res = cpRec;
break;
case META_PAGE_INIT:
cacheId = in.readInt();
pageId = in.readLong();
int ioType = in.readUnsignedShort();
int ioVer = in.readUnsignedShort();
long treeRoot = in.readLong();
long reuseListRoot = in.readLong();
res = new MetaPageInitRecord(cacheId, pageId, ioType, ioVer, treeRoot, reuseListRoot, log);
break;
case INDEX_META_PAGE_DELTA_RECORD:
res = new MetaPageUpdateIndexDataRecord(in);
break;
case PARTITION_META_PAGE_UPDATE_COUNTERS:
res = new MetaPageUpdatePartitionDataRecord(in);
break;
case PARTITION_META_PAGE_UPDATE_COUNTERS_V2:
res = new MetaPageUpdatePartitionDataRecordV2(in);
break;
case PARTITION_META_PAGE_DELTA_RECORD_V3:
res = new MetaPageUpdatePartitionDataRecordV3(in);
break;
case MEMORY_RECOVERY:
long ts = in.readLong();
res = new MemoryRecoveryRecord(ts);
break;
case PARTITION_DESTROY:
cacheId = in.readInt();
int partId = in.readInt();
res = new PartitionDestroyRecord(cacheId, partId);
break;
case DATA_RECORD:
case DATA_RECORD_V2:
int entryCnt = in.readInt();
if (entryCnt == 1)
res = new DataRecord(readPlainDataEntry(in, type), 0L);
else {
List<DataEntry> entries = new ArrayList<>(entryCnt);
for (int i = 0; i < entryCnt; i++) entries.add(readPlainDataEntry(in, type));
res = new DataRecord(entries, 0L);
}
break;
case ENCRYPTED_DATA_RECORD:
case ENCRYPTED_DATA_RECORD_V2:
case ENCRYPTED_DATA_RECORD_V3:
entryCnt = in.readInt();
if (entryCnt == 1)
res = new DataRecord(readEncryptedDataEntry(in, type), 0L);
else {
List<DataEntry> entries = new ArrayList<>(entryCnt);
for (int i = 0; i < entryCnt; i++) entries.add(readEncryptedDataEntry(in, type));
res = new DataRecord(entries, 0L);
}
break;
case METASTORE_DATA_RECORD:
int strLen = in.readInt();
byte[] strBytes = new byte[strLen];
in.readFully(strBytes);
String key = new String(strBytes);
int valLen = in.readInt();
assert valLen >= 0;
byte[] val;
if (valLen > 0) {
val = new byte[valLen];
in.readFully(val);
} else
val = null;
return new MetastoreDataRecord(key, val);
case HEADER_RECORD:
long magic = in.readLong();
if (magic != HeaderRecord.REGULAR_MAGIC && magic != HeaderRecord.COMPACTED_MAGIC)
throw new EOFException("Magic is corrupted [actual=" + U.hexLong(magic) + ']');
int ver = in.readInt();
res = new HeaderRecord(ver);
break;
case DATA_PAGE_INSERT_RECORD:
{
cacheId = in.readInt();
pageId = in.readLong();
int size = in.readUnsignedShort();
in.ensure(size);
byte[] payload = new byte[size];
in.readFully(payload);
res = new DataPageInsertRecord(cacheId, pageId, payload);
break;
}
case DATA_PAGE_UPDATE_RECORD:
{
cacheId = in.readInt();
pageId = in.readLong();
int itemId = in.readInt();
int size = in.readUnsignedShort();
in.ensure(size);
byte[] payload = new byte[size];
in.readFully(payload);
res = new DataPageUpdateRecord(cacheId, pageId, itemId, payload);
break;
}
case DATA_PAGE_INSERT_FRAGMENT_RECORD:
{
cacheId = in.readInt();
pageId = in.readLong();
final long lastLink = in.readLong();
final int payloadSize = in.readInt();
final byte[] payload = new byte[payloadSize];
in.readFully(payload);
res = new DataPageInsertFragmentRecord(cacheId, pageId, payload, lastLink);
break;
}
case DATA_PAGE_REMOVE_RECORD:
cacheId = in.readInt();
pageId = in.readLong();
int itemId = in.readUnsignedByte();
res = new DataPageRemoveRecord(cacheId, pageId, itemId);
break;
case DATA_PAGE_SET_FREE_LIST_PAGE:
cacheId = in.readInt();
pageId = in.readLong();
long freeListPage = in.readLong();
res = new DataPageSetFreeListPageRecord(cacheId, pageId, freeListPage);
break;
case MVCC_DATA_PAGE_MARK_UPDATED_RECORD:
cacheId = in.readInt();
pageId = in.readLong();
itemId = in.readInt();
long newMvccCrd = in.readLong();
long newMvccCntr = in.readLong();
int newMvccOpCntr = in.readInt();
res = new DataPageMvccMarkUpdatedRecord(cacheId, pageId, itemId, newMvccCrd, newMvccCntr, newMvccOpCntr);
break;
case MVCC_DATA_PAGE_TX_STATE_HINT_UPDATED_RECORD:
cacheId = in.readInt();
pageId = in.readLong();
itemId = in.readInt();
byte txState = in.readByte();
res = new DataPageMvccUpdateTxStateHintRecord(cacheId, pageId, itemId, txState);
break;
case MVCC_DATA_PAGE_NEW_TX_STATE_HINT_UPDATED_RECORD:
cacheId = in.readInt();
pageId = in.readLong();
itemId = in.readInt();
byte newTxState = in.readByte();
res = new DataPageMvccUpdateNewTxStateHintRecord(cacheId, pageId, itemId, newTxState);
break;
case INIT_NEW_PAGE_RECORD:
cacheId = in.readInt();
pageId = in.readLong();
ioType = in.readUnsignedShort();
ioVer = in.readUnsignedShort();
long virtualPageId = in.readLong();
res = new InitNewPageRecord(cacheId, pageId, ioType, ioVer, virtualPageId, log);
break;
case BTREE_META_PAGE_INIT_ROOT:
cacheId = in.readInt();
pageId = in.readLong();
long rootId = in.readLong();
res = new MetaPageInitRootRecord(cacheId, pageId, rootId);
break;
case BTREE_META_PAGE_INIT_ROOT2:
cacheId = in.readInt();
pageId = in.readLong();
long rootId2 = in.readLong();
int inlineSize = in.readShort();
res = new MetaPageInitRootInlineRecord(cacheId, pageId, rootId2, inlineSize);
break;
case BTREE_META_PAGE_INIT_ROOT_V3:
cacheId = in.readInt();
pageId = in.readLong();
long rootId3 = in.readLong();
int inlineSize3 = in.readShort();
long flags = in.readLong();
byte[] revHash = new byte[IgniteProductVersion.REV_HASH_SIZE];
byte maj = in.readByte();
byte min = in.readByte();
byte maint = in.readByte();
long verTs = in.readLong();
in.readFully(revHash);
IgniteProductVersion createdVer = new IgniteProductVersion(maj, min, maint, verTs, revHash);
res = new MetaPageInitRootInlineFlagsCreatedVersionRecord(cacheId, pageId, rootId3, inlineSize3, flags, createdVer);
break;
case BTREE_META_PAGE_ADD_ROOT:
cacheId = in.readInt();
pageId = in.readLong();
rootId = in.readLong();
res = new MetaPageAddRootRecord(cacheId, pageId, rootId);
break;
case BTREE_META_PAGE_CUT_ROOT:
cacheId = in.readInt();
pageId = in.readLong();
res = new MetaPageCutRootRecord(cacheId, pageId);
break;
case BTREE_INIT_NEW_ROOT:
cacheId = in.readInt();
pageId = in.readLong();
rootId = in.readLong();
ioType = in.readUnsignedShort();
ioVer = in.readUnsignedShort();
long leftId = in.readLong();
long rightId = in.readLong();
BPlusIO<?> io = BPlusIO.getBPlusIO(ioType, ioVer);
byte[] rowBytes = new byte[io.getItemSize()];
in.readFully(rowBytes);
res = new NewRootInitRecord<>(cacheId, pageId, rootId, (BPlusInnerIO<?>) io, leftId, rowBytes, rightId);
break;
case BTREE_PAGE_RECYCLE:
cacheId = in.readInt();
pageId = in.readLong();
long newPageId = in.readLong();
res = new RecycleRecord(cacheId, pageId, newPageId);
break;
case BTREE_PAGE_INSERT:
cacheId = in.readInt();
pageId = in.readLong();
ioType = in.readUnsignedShort();
ioVer = in.readUnsignedShort();
int itemIdx = in.readUnsignedShort();
rightId = in.readLong();
io = BPlusIO.getBPlusIO(ioType, ioVer);
rowBytes = new byte[io.getItemSize()];
in.readFully(rowBytes);
res = new InsertRecord<>(cacheId, pageId, io, itemIdx, rowBytes, rightId);
break;
case BTREE_FIX_LEFTMOST_CHILD:
cacheId = in.readInt();
pageId = in.readLong();
rightId = in.readLong();
res = new FixLeftmostChildRecord(cacheId, pageId, rightId);
break;
case BTREE_FIX_COUNT:
cacheId = in.readInt();
pageId = in.readLong();
int cnt = in.readUnsignedShort();
res = new FixCountRecord(cacheId, pageId, cnt);
break;
case BTREE_PAGE_REPLACE:
cacheId = in.readInt();
pageId = in.readLong();
ioType = in.readUnsignedShort();
ioVer = in.readUnsignedShort();
itemIdx = in.readUnsignedShort();
io = BPlusIO.getBPlusIO(ioType, ioVer);
rowBytes = new byte[io.getItemSize()];
in.readFully(rowBytes);
res = new ReplaceRecord<>(cacheId, pageId, io, rowBytes, itemIdx);
break;
case BTREE_PAGE_REMOVE:
cacheId = in.readInt();
pageId = in.readLong();
itemIdx = in.readUnsignedShort();
cnt = in.readUnsignedShort();
res = new RemoveRecord(cacheId, pageId, itemIdx, cnt);
break;
case BTREE_PAGE_INNER_REPLACE:
cacheId = in.readInt();
pageId = in.readLong();
int dstIdx = in.readUnsignedShort();
long srcPageId = in.readLong();
int srcIdx = in.readUnsignedShort();
long rmvId = in.readLong();
res = new InnerReplaceRecord<>(cacheId, pageId, dstIdx, srcPageId, srcIdx, rmvId);
break;
case BTREE_FORWARD_PAGE_SPLIT:
cacheId = in.readInt();
pageId = in.readLong();
long fwdId = in.readLong();
ioType = in.readUnsignedShort();
ioVer = in.readUnsignedShort();
srcPageId = in.readLong();
int mid = in.readUnsignedShort();
cnt = in.readUnsignedShort();
res = new SplitForwardPageRecord(cacheId, pageId, fwdId, ioType, ioVer, srcPageId, mid, cnt);
break;
case BTREE_EXISTING_PAGE_SPLIT:
cacheId = in.readInt();
pageId = in.readLong();
mid = in.readUnsignedShort();
fwdId = in.readLong();
res = new SplitExistingPageRecord(cacheId, pageId, mid, fwdId);
break;
case BTREE_PAGE_MERGE:
cacheId = in.readInt();
pageId = in.readLong();
long prntId = in.readLong();
int prntIdx = in.readUnsignedShort();
rightId = in.readLong();
boolean emptyBranch = in.readBoolean();
res = new MergeRecord<>(cacheId, pageId, prntId, prntIdx, rightId, emptyBranch);
break;
case BTREE_FIX_REMOVE_ID:
cacheId = in.readInt();
pageId = in.readLong();
rmvId = in.readLong();
res = new FixRemoveId(cacheId, pageId, rmvId);
break;
case PAGES_LIST_SET_NEXT:
cacheId = in.readInt();
pageId = in.readLong();
long nextPageId = in.readLong();
res = new PagesListSetNextRecord(cacheId, pageId, nextPageId);
break;
case PAGES_LIST_SET_PREVIOUS:
cacheId = in.readInt();
pageId = in.readLong();
long prevPageId = in.readLong();
res = new PagesListSetPreviousRecord(cacheId, pageId, prevPageId);
break;
case PAGES_LIST_INIT_NEW_PAGE:
cacheId = in.readInt();
pageId = in.readLong();
ioType = in.readInt();
ioVer = in.readInt();
newPageId = in.readLong();
prevPageId = in.readLong();
long addDataPageId = in.readLong();
res = new PagesListInitNewPageRecord(cacheId, pageId, ioType, ioVer, newPageId, prevPageId, addDataPageId, log);
break;
case PAGES_LIST_ADD_PAGE:
cacheId = in.readInt();
pageId = in.readLong();
long dataPageId = in.readLong();
res = new PagesListAddPageRecord(cacheId, pageId, dataPageId);
break;
case PAGES_LIST_REMOVE_PAGE:
cacheId = in.readInt();
pageId = in.readLong();
long rmvdPageId = in.readLong();
res = new PagesListRemovePageRecord(cacheId, pageId, rmvdPageId);
break;
case TRACKING_PAGE_DELTA:
cacheId = in.readInt();
pageId = in.readLong();
long pageIdToMark = in.readLong();
long nextSnapshotId0 = in.readLong();
long lastSuccessfulSnapshotId0 = in.readLong();
res = new TrackingPageDeltaRecord(cacheId, pageId, pageIdToMark, nextSnapshotId0, lastSuccessfulSnapshotId0);
break;
case META_PAGE_UPDATE_NEXT_SNAPSHOT_ID:
cacheId = in.readInt();
pageId = in.readLong();
long nextSnapshotId = in.readLong();
res = new MetaPageUpdateNextSnapshotId(cacheId, pageId, nextSnapshotId);
break;
case META_PAGE_UPDATE_LAST_SUCCESSFUL_FULL_SNAPSHOT_ID:
cacheId = in.readInt();
pageId = in.readLong();
long lastSuccessfulFullSnapshotId = in.readLong();
res = new MetaPageUpdateLastSuccessfulFullSnapshotId(cacheId, pageId, lastSuccessfulFullSnapshotId);
break;
case META_PAGE_UPDATE_LAST_SUCCESSFUL_SNAPSHOT_ID:
cacheId = in.readInt();
pageId = in.readLong();
long lastSuccessfulSnapshotId = in.readLong();
long lastSuccessfulSnapshotTag = in.readLong();
res = new MetaPageUpdateLastSuccessfulSnapshotId(cacheId, pageId, lastSuccessfulSnapshotId, lastSuccessfulSnapshotTag);
break;
case META_PAGE_UPDATE_LAST_ALLOCATED_INDEX:
cacheId = in.readInt();
pageId = in.readLong();
int lastAllocatedIdx = in.readInt();
res = new MetaPageUpdateLastAllocatedIndex(cacheId, pageId, lastAllocatedIdx);
break;
case PART_META_UPDATE_STATE:
cacheId = in.readInt();
partId = in.readInt();
byte state = in.readByte();
long updateCntr = in.readLong();
GridDhtPartitionState partState = GridDhtPartitionState.fromOrdinal(state);
res = new PartitionMetaStateRecord(cacheId, partId, partState, updateCntr);
break;
case PAGE_LIST_META_RESET_COUNT_RECORD:
cacheId = in.readInt();
pageId = in.readLong();
res = new PageListMetaResetCountRecord(cacheId, pageId);
break;
case ROTATED_ID_PART_RECORD:
cacheId = in.readInt();
pageId = in.readLong();
byte rotatedIdPart = in.readByte();
res = new RotatedIdPartRecord(cacheId, pageId, rotatedIdPart);
break;
case SWITCH_SEGMENT_RECORD:
throw new EOFException("END OF SEGMENT");
case TX_RECORD:
res = txRecordSerializer.readTx(in);
break;
case MASTER_KEY_CHANGE_RECORD:
case MASTER_KEY_CHANGE_RECORD_V2:
int keyNameLen = in.readInt();
byte[] keyNameBytes = new byte[keyNameLen];
in.readFully(keyNameBytes);
String masterKeyName = new String(keyNameBytes);
int keysCnt = in.readInt();
List<T2<Integer, GroupKeyEncrypted>> grpKeys = new ArrayList<>(keysCnt);
boolean readKeyId = type == MASTER_KEY_CHANGE_RECORD_V2;
for (int i = 0; i < keysCnt; i++) {
int grpId = in.readInt();
int keyId = readKeyId ? in.readByte() & 0xff : 0;
int grpKeySize = in.readInt();
byte[] grpKey = new byte[grpKeySize];
in.readFully(grpKey);
grpKeys.add(new T2<>(grpId, new GroupKeyEncrypted(keyId, grpKey)));
}
res = new MasterKeyChangeRecordV2(masterKeyName, grpKeys);
break;
case REENCRYPTION_START_RECORD:
int grpsCnt = in.readInt();
Map<Integer, Byte> map = U.newHashMap(grpsCnt);
for (int i = 0; i < grpsCnt; i++) {
int grpId = in.readInt();
byte keyId = in.readByte();
map.put(grpId, keyId);
}
res = new ReencryptionStartRecord(map);
break;
case INDEX_ROOT_PAGE_RENAME_RECORD:
res = new IndexRenameRootPageRecord(in);
break;
case PARTITION_CLEARING_START_RECORD:
int partId0 = in.readInt();
int grpId = in.readInt();
long clearVer = in.readLong();
res = new PartitionClearingStartRecord(partId0, grpId, clearVer);
break;
default:
throw new UnsupportedOperationException("Type: " + type);
}
return res;
}
use of org.apache.ignite.internal.pagemem.wal.record.PageSnapshot in project ignite by apache.
the class FileWriteAheadLogManager method log.
/**
* {@inheritDoc}
*/
@Override
public WALPointer log(WALRecord rec, RolloverType rolloverType) throws IgniteCheckedException {
if (serializer == null || mode == WALMode.NONE)
return null;
// Only delta-records, page snapshots and memory recovery are allowed to write in recovery mode.
if (cctx.kernalContext().recoveryMode() && !(rec instanceof PageDeltaRecord || rec instanceof PageSnapshot || rec instanceof MemoryRecoveryRecord))
return null;
FileWriteHandle currWrHandle = currentHandle();
WALDisableContext isDisable = walDisableContext;
// Logging was not resumed yet.
if (currWrHandle == null || (isDisable != null && isDisable.check()))
return null;
// Do page snapshots compression if configured.
if (pageCompression != DiskPageCompression.DISABLED && rec instanceof PageSnapshot) {
PageSnapshot pageSnapshot = (PageSnapshot) rec;
int pageSize = pageSnapshot.realPageSize();
ByteBuffer pageData = pageSnapshot.pageDataBuffer();
ByteBuffer compressedPage = cctx.kernalContext().compress().compressPage(pageData, pageSize, 1, pageCompression, pageCompressionLevel);
if (compressedPage != pageData) {
assert compressedPage.isDirect() : "Is direct buffer: " + compressedPage.isDirect();
rec = new PageSnapshot(pageSnapshot.fullPageId(), GridUnsafe.bufferAddress(compressedPage), compressedPage.limit(), pageSize);
}
}
// Need to calculate record size first.
rec.size(serializer.size(rec));
while (true) {
WALPointer ptr;
if (rolloverType == RolloverType.NONE)
ptr = currWrHandle.addRecord(rec);
else {
assert cctx.database().checkpointLockIsHeldByThread();
if (rolloverType == RolloverType.NEXT_SEGMENT) {
WALPointer pos = rec.position();
do {
// This will change rec.position() unless concurrent rollover happened.
currWrHandle = closeBufAndRollover(currWrHandle, rec, rolloverType);
} while (Objects.equals(pos, rec.position()));
ptr = rec.position();
} else if (rolloverType == RolloverType.CURRENT_SEGMENT) {
if ((ptr = currWrHandle.addRecord(rec)) != null)
currWrHandle = closeBufAndRollover(currWrHandle, rec, rolloverType);
} else
throw new IgniteCheckedException("Unknown rollover type: " + rolloverType);
}
if (ptr != null) {
metrics.onWalRecordLogged(rec.size());
if (walAutoArchiveAfterInactivity > 0 || walForceArchiveTimeout > 0) {
long millis = U.currentTimeMillis();
lastRecordLoggedMs.set(millis);
// No need to forcefully rollover for other record types.
if (walForceArchiveTimeout > 0 && rec.type() == DATA_RECORD_V2)
lastDataRecordLoggedMs.set(millis);
}
return ptr;
} else
currWrHandle = rollOver(currWrHandle, null);
checkNode();
if (isStopping())
throw new IgniteCheckedException("Stopping.");
}
}
use of org.apache.ignite.internal.pagemem.wal.record.PageSnapshot in project ignite by apache.
the class CorruptedTreeFailureHandlingTest method testCorruptedPage.
/**
* Check that if a corrupted page exists, an {@link CorruptedTreeException}
* will be thrown and a diagnostic file will be generated.
*
* @throws Exception If failed.
*/
@Test
public void testCorruptedPage() throws Exception {
IgniteEx srv = startGrid(0);
File diagnosticDir = new File(srv.context().config().getWorkDirectory(), "diagnostic");
FileUtils.deleteDirectory(diagnosticDir);
srv.cluster().state(ClusterState.ACTIVE);
IgniteCache<Integer, Integer> cache = srv.getOrCreateCache(DEFAULT_CACHE_NAME);
for (int i = 0; i < 10; i++) cache.put(i, i);
int pageSize = srv.configuration().getDataStorageConfiguration().getPageSize();
int grpId = srv.context().cache().cacheGroups().stream().filter(context -> context.cacheOrGroupName().equals(DEFAULT_CACHE_NAME)).findAny().orElseThrow(() -> new RuntimeException("Cache group not found")).groupId();
stopGrid(0, false);
// Node is stopped, we're ready to corrupt partition data.
long link = linkRef.get();
long pageId = PageIdUtils.pageId(link);
int itemId = PageIdUtils.itemId(link);
ByteBuffer pageBuf = ByteBuffer.allocateDirect(pageSize);
OpenOption[] options = { StandardOpenOption.READ, StandardOpenOption.WRITE };
try (RandomAccessFileIO fileIO = new RandomAccessFileIO(fileRef.get(), options)) {
DataPageIO dataPageIO = DataPageIO.VERSIONS.latest();
long pageOff = pageSize + PageIdUtils.pageIndex(pageId) * pageSize;
// Read index page.
fileIO.position(pageOff);
fileIO.readFully(pageBuf);
long pageAddr = GridUnsafe.bufferAddress(pageBuf);
// Remove existing item from index page.
dataPageIO.removeRow(pageAddr, itemId, pageSize);
// Recalculate CRC.
PageIO.setCrc(pageAddr, 0);
pageBuf.rewind();
PageIO.setCrc(pageAddr, FastCrc.calcCrc(pageBuf, pageSize));
// Write it back.
pageBuf.rewind();
fileIO.position(pageOff);
fileIO.writeFully(pageBuf);
}
LogListener logLsnr = LogListener.matches("CorruptedTreeException has occurred. " + "To diagnose it, make a backup of the following directories: ").build();
srv = startGrid(0, cfg -> {
cfg.setGridLogger(new ListeningTestLogger(cfg.getGridLogger(), logLsnr));
});
// Add modified page to WAL so it won't be restored to previous (valid) state.
pageBuf.rewind();
ByteBuffer cpBuf = ByteBuffer.allocate(pageBuf.capacity());
cpBuf.put(pageBuf);
PageSnapshot pageSnapshot = new PageSnapshot(new FullPageId(pageId, grpId), cpBuf.array(), pageSize);
srv.context().cache().context().wal().log(pageSnapshot);
// Access cache.
cache = srv.cache(DEFAULT_CACHE_NAME);
try {
for (int i = 0; i < CACHE_ENTRIES; i++) cache.get(i);
fail("Cache operations are expected to fail");
} catch (Throwable e) {
assertTrue(X.hasCause(e, CorruptedTreeException.class));
}
assertTrue(GridTestUtils.waitForCondition(() -> G.allGrids().isEmpty(), 10_000L));
assertTrue(diagnosticDir.exists());
assertTrue(diagnosticDir.isDirectory());
Pattern corruptedPagesFileNamePtrn = corruptedPagesFileNamePattern();
File[] txtFiles = diagnosticDir.listFiles((dir, name) -> corruptedPagesFileNamePtrn.matcher(name).matches());
assertFalse(F.isEmpty(txtFiles));
assertEquals(1, txtFiles.length);
assertTrue(logLsnr.check());
}
use of org.apache.ignite.internal.pagemem.wal.record.PageSnapshot in project ignite by apache.
the class IgnitePdsCheckpointSimulationWithRealCpDisabledTest method testGetForInitialWrite.
/**
* @throws Exception if failed.
*/
@Test
public void testGetForInitialWrite() throws Exception {
IgniteEx ig = startGrid(0);
ig.cluster().active(true);
GridCacheSharedContext<Object, Object> shared = ig.context().cache().context();
int cacheId = shared.cache().cache(CACHE_NAME).context().cacheId();
GridCacheDatabaseSharedManager dbMgr = (GridCacheDatabaseSharedManager) shared.database();
// Disable integrated checkpoint thread.
dbMgr.enableCheckpoints(false);
PageMemory mem = shared.database().dataRegion(null).pageMemory();
IgniteWriteAheadLogManager wal = shared.wal();
WALPointer start = wal.log(new CheckpointRecord(null));
final FullPageId[] initWrites = new FullPageId[10];
ig.context().cache().context().database().checkpointReadLock();
try {
for (int i = 0; i < initWrites.length; i++) initWrites[i] = new FullPageId(mem.allocatePage(cacheId, 0, PageIdAllocator.FLAG_DATA), cacheId);
// Check getForInitialWrite methods.
for (FullPageId fullId : initWrites) {
long page = mem.acquirePage(fullId.groupId(), fullId.pageId());
try {
long pageAddr = mem.writeLock(fullId.groupId(), fullId.pageId(), page);
try {
DataPageIO.VERSIONS.latest().initNewPage(pageAddr, fullId.pageId(), mem.realPageSize(fullId.groupId()), null);
for (int i = PageIO.COMMON_HEADER_END + DataPageIO.ITEMS_OFF; i < mem.pageSize(); i++) PageUtils.putByte(pageAddr, i, (byte) 0xAB);
PageIO.printPage(pageAddr, mem.realPageSize(fullId.groupId()));
} finally {
mem.writeUnlock(fullId.groupId(), fullId.pageId(), page, null, true);
}
} finally {
mem.releasePage(fullId.groupId(), fullId.pageId(), page);
}
}
wal.flush(null, false);
} finally {
ig.context().cache().context().database().checkpointReadUnlock();
stopAllGrids(false);
}
ig = startGrid(0);
ig.cluster().active(true);
shared = ig.context().cache().context();
dbMgr = (GridCacheDatabaseSharedManager) shared.database();
dbMgr.enableCheckpoints(false);
wal = shared.wal();
try (PartitionMetaStateRecordExcludeIterator it = new PartitionMetaStateRecordExcludeIterator(wal.replay(start))) {
it.next();
for (FullPageId initialWrite : initWrites) {
IgniteBiTuple<WALPointer, WALRecord> tup = it.next();
assertTrue(String.valueOf(tup.get2()), tup.get2() instanceof PageSnapshot);
PageSnapshot snap = (PageSnapshot) tup.get2();
FullPageId actual = snap.fullPageId();
// there are extra tracking pages, skip them
if (TrackingPageIO.VERSIONS.latest().trackingPageFor(actual.pageId(), mem.pageSize()) == actual.pageId()) {
tup = it.next();
assertTrue(tup.get2() instanceof PageSnapshot);
actual = ((PageSnapshot) tup.get2()).fullPageId();
}
assertEquals(initialWrite, actual);
}
}
}
use of org.apache.ignite.internal.pagemem.wal.record.PageSnapshot in project ignite by apache.
the class IgnitePdsCheckpointSimulationWithRealCpDisabledTest method verifyReads.
/**
* @param res Result map to verify.
* @param mem Memory.
*/
private void verifyReads(GridKernalContext ctx, Map<FullPageId, Integer> res, PageMemory mem, WALPointer start, IgniteWriteAheadLogManager wal) throws Exception {
Map<FullPageId, byte[]> replay = new HashMap<>();
ByteBuffer buf = ByteBuffer.allocateDirect(mem.pageSize()).order(ByteOrder.nativeOrder());
try (PartitionMetaStateRecordExcludeIterator it = new PartitionMetaStateRecordExcludeIterator(wal.replay(start))) {
IgniteBiTuple<WALPointer, WALRecord> tup = it.next();
assertTrue("Invalid record: " + tup, tup.get2() instanceof CheckpointRecord);
CheckpointRecord cpRec = (CheckpointRecord) tup.get2();
while (it.hasNext()) {
tup = it.next();
WALRecord rec = tup.get2();
if (rec instanceof CheckpointRecord) {
CheckpointRecord end = (CheckpointRecord) rec;
// Found the finish mark.
if (end.checkpointId().equals(cpRec.checkpointId()) && end.end())
break;
} else if (rec instanceof PageSnapshot) {
PageSnapshot page = (PageSnapshot) rec;
int realPageSize = mem.realPageSize(page.groupId());
byte[] pageData = page.pageData();
if (page.pageDataSize() < realPageSize) {
buf.clear();
buf.put(pageData).flip();
ctx.compress().decompressPage(buf, realPageSize);
pageData = new byte[buf.limit()];
buf.get(pageData);
}
replay.put(page.fullPageId(), pageData);
}
}
}
// Check read-through from the file store.
for (Map.Entry<FullPageId, Integer> entry : res.entrySet()) {
FullPageId fullId = entry.getKey();
int state = entry.getValue();
if (state == -1) {
info("Page was never written: " + fullId);
continue;
}
byte[] walData = replay.get(fullId);
assertNotNull("Missing WAL record for a written page: " + fullId, walData);
long page = mem.acquirePage(fullId.groupId(), fullId.pageId());
try {
long pageAddr = mem.readLock(fullId.groupId(), fullId.pageId(), page);
try {
for (int i = PageIO.COMMON_HEADER_END; i < mem.realPageSize(fullId.groupId()); i++) {
int expState = state & 0xFF;
int pageState = PageUtils.getByte(pageAddr, i) & 0xFF;
int walState = walData[i] & 0xFF;
if (expState != pageState)
assertEquals("Invalid state [pageId=" + fullId + ", pos=" + i + ']', expState, pageState);
if (expState != walState)
assertEquals("Invalid WAL state [pageId=" + fullId + ", pos=" + i + ']', expState, walState);
}
} finally {
mem.readUnlock(fullId.groupId(), fullId.pageId(), page);
}
} finally {
mem.releasePage(fullId.groupId(), fullId.pageId(), page);
}
}
}
Aggregations