use of org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMemoryEx in project ignite by apache.
the class GridCacheDatabaseSharedManager method restoreMemory.
/**
* @param status Checkpoint status.
* @param storeOnly If {@code True} restores Metastorage only.
*/
private WALPointer restoreMemory(CheckpointStatus status, boolean storeOnly, PageMemoryEx storePageMem) throws IgniteCheckedException {
assert !storeOnly || storePageMem != null;
if (log.isInfoEnabled())
log.info("Checking memory state [lastValidPos=" + status.endPtr + ", lastMarked=" + status.startPtr + ", lastCheckpointId=" + status.cpStartId + ']');
boolean apply = status.needRestoreMemory();
if (apply) {
U.quietAndWarn(log, "Ignite node stopped in the middle of checkpoint. Will restore memory state and " + "finish checkpoint on node start.");
cctx.pageStore().beginRecover();
} else
cctx.wal().allowCompressionUntil(status.startPtr);
long start = U.currentTimeMillis();
int applied = 0;
WALPointer lastRead = null;
Collection<Integer> ignoreGrps = storeOnly ? Collections.emptySet() : initiallyWalDisabledGrps;
try (WALIterator it = cctx.wal().replay(status.endPtr)) {
while (it.hasNextX()) {
IgniteBiTuple<WALPointer, WALRecord> tup = it.nextX();
WALRecord rec = tup.get2();
lastRead = tup.get1();
switch(rec.type()) {
case CHECKPOINT_RECORD:
CheckpointRecord cpRec = (CheckpointRecord) rec;
// We roll memory up until we find a checkpoint start record registered in the status.
if (F.eq(cpRec.checkpointId(), status.cpStartId)) {
log.info("Found last checkpoint marker [cpId=" + cpRec.checkpointId() + ", pos=" + tup.get1() + ']');
apply = false;
} else if (!F.eq(cpRec.checkpointId(), status.cpEndId))
U.warn(log, "Found unexpected checkpoint marker, skipping [cpId=" + cpRec.checkpointId() + ", expCpId=" + status.cpStartId + ", pos=" + tup.get1() + ']');
break;
case PAGE_RECORD:
if (apply) {
PageSnapshot pageRec = (PageSnapshot) rec;
// Here we do not require tag check because we may be applying memory changes after
// several repetitive restarts and the same pages may have changed several times.
int grpId = pageRec.fullPageId().groupId();
if (storeOnly && grpId != METASTORAGE_CACHE_ID)
continue;
if (!ignoreGrps.contains(grpId)) {
long pageId = pageRec.fullPageId().pageId();
PageMemoryEx pageMem = grpId == METASTORAGE_CACHE_ID ? storePageMem : getPageMemoryForCacheGroup(grpId);
long page = pageMem.acquirePage(grpId, pageId, true);
try {
long pageAddr = pageMem.writeLock(grpId, pageId, page);
try {
PageUtils.putBytes(pageAddr, 0, pageRec.pageData());
} finally {
pageMem.writeUnlock(grpId, pageId, page, null, true, true);
}
} finally {
pageMem.releasePage(grpId, pageId, page);
}
applied++;
}
}
break;
case PARTITION_DESTROY:
PartitionDestroyRecord destroyRec = (PartitionDestroyRecord) rec;
final int gId = destroyRec.groupId();
if (storeOnly && gId != METASTORAGE_CACHE_ID)
continue;
if (!ignoreGrps.contains(gId)) {
final int pId = destroyRec.partitionId();
PageMemoryEx pageMem = gId == METASTORAGE_CACHE_ID ? storePageMem : getPageMemoryForCacheGroup(gId);
pageMem.clearAsync((grpId, pageId) -> grpId == gId && PageIdUtils.partId(pageId) == pId, true).get();
}
break;
default:
if (apply && rec instanceof PageDeltaRecord) {
PageDeltaRecord r = (PageDeltaRecord) rec;
int grpId = r.groupId();
if (storeOnly && grpId != METASTORAGE_CACHE_ID)
continue;
if (!ignoreGrps.contains(grpId)) {
long pageId = r.pageId();
PageMemoryEx pageMem = grpId == METASTORAGE_CACHE_ID ? storePageMem : getPageMemoryForCacheGroup(grpId);
// Here we do not require tag check because we may be applying memory changes after
// several repetitive restarts and the same pages may have changed several times.
long page = pageMem.acquirePage(grpId, pageId, true);
try {
long pageAddr = pageMem.writeLock(grpId, pageId, page);
try {
r.applyDelta(pageMem, pageAddr);
} finally {
pageMem.writeUnlock(grpId, pageId, page, null, true, true);
}
} finally {
pageMem.releasePage(grpId, pageId, page);
}
applied++;
}
}
}
}
}
if (storeOnly)
return null;
if (status.needRestoreMemory()) {
if (apply)
throw new IgniteCheckedException("Failed to restore memory state (checkpoint marker is present " + "on disk, but checkpoint record is missed in WAL) " + "[cpStatus=" + status + ", lastRead=" + lastRead + "]");
log.info("Finished applying memory changes [changesApplied=" + applied + ", time=" + (U.currentTimeMillis() - start) + "ms]");
if (applied > 0)
finalizeCheckpointOnRecovery(status.cpStartTs, status.cpStartId, status.startPtr);
}
checkpointHist.loadHistory(cpDir);
return lastRead == null ? null : lastRead.next();
}
use of org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMemoryEx in project ignite by apache.
the class GridCacheDatabaseSharedManager method createPageMemory.
/**
* {@inheritDoc}
*/
@Override
protected PageMemory createPageMemory(DirectMemoryProvider memProvider, DataStorageConfiguration memCfg, DataRegionConfiguration plcCfg, DataRegionMetricsImpl memMetrics, final boolean trackable) {
if (!plcCfg.isPersistenceEnabled())
return super.createPageMemory(memProvider, memCfg, plcCfg, memMetrics, trackable);
memMetrics.persistenceEnabled(true);
long cacheSize = plcCfg.getMaxSize();
// Checkpoint buffer size can not be greater than cache size, it does not make sense.
long chpBufSize = checkpointBufferSize(plcCfg);
if (chpBufSize > cacheSize) {
U.quietAndInfo(log, "Configured checkpoint page buffer size is too big, setting to the max region size [size=" + U.readableSize(cacheSize, false) + ", memPlc=" + plcCfg.getName() + ']');
chpBufSize = cacheSize;
}
GridInClosure3X<Long, FullPageId, PageMemoryEx> changeTracker;
if (trackable)
changeTracker = new GridInClosure3X<Long, FullPageId, PageMemoryEx>() {
@Override
public void applyx(Long page, FullPageId fullId, PageMemoryEx pageMem) throws IgniteCheckedException {
if (trackable)
snapshotMgr.onChangeTrackerPage(page, fullId, pageMem);
}
};
else
changeTracker = null;
PageMemoryImpl pageMem = new PageMemoryImpl(memProvider, calculateFragmentSizes(memCfg.getConcurrencyLevel(), cacheSize, chpBufSize), cctx, memCfg.getPageSize(), (fullId, pageBuf, tag) -> {
// First of all, write page to disk.
storeMgr.write(fullId.groupId(), fullId.pageId(), pageBuf, tag);
// Only after write we can write page into snapshot.
snapshotMgr.flushDirtyPageHandler(fullId, pageBuf, tag);
AtomicInteger cntr = evictedPagesCntr;
if (cntr != null)
cntr.incrementAndGet();
}, changeTracker, this, memMetrics, resolveThrottlingPolicy(), this);
memMetrics.pageMemory(pageMem);
return pageMem;
}
use of org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMemoryEx in project ignite by apache.
the class GridCacheDatabaseSharedManager method restorePartitionState.
/**
* @param partStates Partition states.
* @throws IgniteCheckedException If failed to restore.
*/
private void restorePartitionState(Map<T2<Integer, Integer>, T2<Integer, Long>> partStates, Collection<Integer> ignoreGrps) throws IgniteCheckedException {
for (CacheGroupContext grp : cctx.cache().cacheGroups()) {
if (grp.isLocal() || !grp.affinityNode() || ignoreGrps.contains(grp.groupId())) {
// Local cache has no partitions and its states.
continue;
}
if (!grp.dataRegion().config().isPersistenceEnabled())
continue;
int grpId = grp.groupId();
PageMemoryEx pageMem = (PageMemoryEx) grp.dataRegion().pageMemory();
for (int i = 0; i < grp.affinity().partitions(); i++) {
T2<Integer, Long> restore = partStates.get(new T2<>(grpId, i));
if (storeMgr.exists(grpId, i)) {
storeMgr.ensure(grpId, i);
if (storeMgr.pages(grpId, i) <= 1)
continue;
GridDhtLocalPartition part = grp.topology().forceCreatePartition(i);
assert part != null;
// TODO: https://issues.apache.org/jira/browse/IGNITE-6097
grp.offheap().onPartitionInitialCounterUpdated(i, 0);
checkpointReadLock();
try {
long partMetaId = pageMem.partitionMetaPageId(grpId, i);
long partMetaPage = pageMem.acquirePage(grpId, partMetaId);
try {
long pageAddr = pageMem.writeLock(grpId, partMetaId, partMetaPage);
boolean changed = false;
try {
PagePartitionMetaIO io = PagePartitionMetaIO.VERSIONS.forPage(pageAddr);
if (restore != null) {
int stateId = restore.get1();
io.setPartitionState(pageAddr, (byte) stateId);
changed = updateState(part, stateId);
if (stateId == GridDhtPartitionState.OWNING.ordinal() || (stateId == GridDhtPartitionState.MOVING.ordinal() && part.initialUpdateCounter() < restore.get2())) {
part.initialUpdateCounter(restore.get2());
changed = true;
}
} else
updateState(part, (int) io.getPartitionState(pageAddr));
} finally {
pageMem.writeUnlock(grpId, partMetaId, partMetaPage, null, changed);
}
} finally {
pageMem.releasePage(grpId, partMetaId, partMetaPage);
}
} finally {
checkpointReadUnlock();
}
} else if (restore != null) {
GridDhtLocalPartition part = grp.topology().forceCreatePartition(i);
assert part != null;
// TODO: https://issues.apache.org/jira/browse/IGNITE-6097
grp.offheap().onPartitionInitialCounterUpdated(i, 0);
updateState(part, restore.get1());
}
}
// After partition states are restored, it is necessary to update internal data structures in topology.
grp.topology().afterStateRestored(grp.topology().lastTopologyChangeVersion());
}
}
use of org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMemoryEx in project ignite by apache.
the class GridCacheOffheapManager method getOrAllocateCacheMetas.
/**
* @return Meta root pages info.
* @throws IgniteCheckedException If failed.
*/
private Metas getOrAllocateCacheMetas() throws IgniteCheckedException {
PageMemoryEx pageMem = (PageMemoryEx) grp.dataRegion().pageMemory();
IgniteWriteAheadLogManager wal = ctx.wal();
int grpId = grp.groupId();
long metaId = pageMem.metaPageId(grpId);
long metaPage = pageMem.acquirePage(grpId, metaId);
try {
final long pageAddr = pageMem.writeLock(grpId, metaId, metaPage);
boolean allocated = false;
try {
long metastoreRoot, reuseListRoot;
if (PageIO.getType(pageAddr) != PageIO.T_META) {
PageMetaIO pageIO = PageMetaIO.VERSIONS.latest();
pageIO.initNewPage(pageAddr, metaId, pageMem.pageSize());
metastoreRoot = pageMem.allocatePage(grpId, PageIdAllocator.INDEX_PARTITION, PageMemory.FLAG_IDX);
reuseListRoot = pageMem.allocatePage(grpId, PageIdAllocator.INDEX_PARTITION, PageMemory.FLAG_IDX);
pageIO.setTreeRoot(pageAddr, metastoreRoot);
pageIO.setReuseListRoot(pageAddr, reuseListRoot);
if (PageHandler.isWalDeltaRecordNeeded(pageMem, grpId, metaId, metaPage, wal, null))
wal.log(new MetaPageInitRecord(grpId, metaId, pageIO.getType(), pageIO.getVersion(), metastoreRoot, reuseListRoot));
allocated = true;
} else {
PageMetaIO pageIO = PageIO.getPageIO(pageAddr);
metastoreRoot = pageIO.getTreeRoot(pageAddr);
reuseListRoot = pageIO.getReuseListRoot(pageAddr);
assert reuseListRoot != 0L;
}
return new Metas(new RootPage(new FullPageId(metastoreRoot, grpId), allocated), new RootPage(new FullPageId(reuseListRoot, grpId), allocated));
} finally {
pageMem.writeUnlock(grpId, metaId, metaPage, null, allocated);
}
} finally {
pageMem.releasePage(grpId, metaId, metaPage);
}
}
use of org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMemoryEx in project ignite by apache.
the class GridCacheOffheapManager method saveMeta.
/**
* @param ctx Context.
*/
private void saveMeta(Context ctx) throws IgniteCheckedException {
int grpId = grp.groupId();
PageMemoryEx pageMem = (PageMemoryEx) grp.dataRegion().pageMemory();
IgniteWriteAheadLogManager wal = this.ctx.wal();
long metaPageId = pageMem.metaPageId(grpId);
long metaPage = pageMem.acquirePage(grpId, metaPageId);
try {
long metaPageAddr = pageMem.writeLock(grpId, metaPageId, metaPage);
try {
PageMetaIO metaIo = PageMetaIO.getPageIO(metaPageAddr);
long nextSnapshotTag = metaIo.getNextSnapshotTag(metaPageAddr);
metaIo.setNextSnapshotTag(metaPageAddr, nextSnapshotTag + 1);
if (log != null && log.isDebugEnabled())
log.debug("Save next snapshot before checkpoint start for grId = " + grpId + ", nextSnapshotTag = " + nextSnapshotTag);
if (PageHandler.isWalDeltaRecordNeeded(pageMem, grpId, metaPageId, metaPage, wal, null))
wal.log(new MetaPageUpdateNextSnapshotId(grpId, metaPageId, nextSnapshotTag + 1));
addPartition(null, ctx.partitionStatMap(), metaPageAddr, metaIo, grpId, PageIdAllocator.INDEX_PARTITION, this.ctx.pageStore().pages(grpId, PageIdAllocator.INDEX_PARTITION), -1);
} finally {
pageMem.writeUnlock(grpId, metaPageId, metaPage, null, true);
}
} finally {
pageMem.releasePage(grpId, metaPageId, metaPage);
}
}
Aggregations