use of org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMemoryImpl 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, PageReadWriteManager pmPageMgr) {
if (!plcCfg.isPersistenceEnabled())
return super.createPageMemory(memProvider, memCfg, plcCfg, memMetrics, trackable, pmPageMgr);
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(wrapMetricsPersistentMemoryProvider(memProvider, memMetrics), calculateFragmentSizes(memCfg.getConcurrencyLevel(), cacheSize, chpBufSize), cctx, pmPageMgr, memCfg.getPageSize(), (fullId, pageBuf, tag) -> {
memMetrics.onPageWritten();
// We can write only page from disk into snapshot.
snapshotMgr.beforePageWrite(fullId);
// Write page to disk.
pmPageMgr.write(fullId.groupId(), fullId.pageId(), pageBuf, tag, true);
getCheckpointer().currentProgress().updateEvictedPages(1);
}, changeTracker, this, memMetrics, resolveThrottlingPolicy(), () -> getCheckpointer().currentProgress());
memMetrics.pageMemory(pageMem);
return pageMem;
}
use of org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMemoryImpl in project ignite by apache.
the class IgnitePdsCheckpointSimulationWithRealCpDisabledTest method testCheckpointSimulationMultiThreaded.
/**
* @throws Exception if failed.
*/
@Test
public void testCheckpointSimulationMultiThreaded() throws Exception {
IgniteEx ig = startGrid(0);
ig.cluster().active(true);
GridCacheSharedContext<Object, Object> shared = ig.context().cache().context();
GridCacheDatabaseSharedManager dbMgr = (GridCacheDatabaseSharedManager) shared.database();
IgnitePageStoreManager pageStore = shared.pageStore();
U.sleep(1_000);
// Disable integrated checkpoint thread.
dbMgr.enableCheckpoints(false).get();
// Must put something in partition 0 in order to initialize meta page.
// Otherwise we will violate page store integrity rules.
ig.cache(CACHE_NAME).put(0, 0);
PageMemory mem = shared.database().dataRegion(null).pageMemory();
IgniteBiTuple<Map<FullPageId, Integer>, WALPointer> res;
try {
res = runCheckpointing(ig, (PageMemoryImpl) mem, pageStore, shared.wal(), shared.cache().cache(CACHE_NAME).context().cacheId());
} catch (Throwable th) {
log().error("Error while running checkpointing", th);
throw th;
} finally {
dbMgr.enableCheckpoints(true).get();
stopAllGrids(false);
}
ig = startGrid(0);
ig.cluster().active(true);
shared = ig.context().cache().context();
dbMgr = (GridCacheDatabaseSharedManager) shared.database();
dbMgr.enableCheckpoints(false).get();
mem = shared.database().dataRegion(null).pageMemory();
verifyReads(ig.context(), res.get1(), mem, res.get2(), shared.wal());
}
use of org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMemoryImpl in project ignite by apache.
the class ProgressWatchdog method tick.
/**
* Regular method printing statistics to out and to log. Checks gaps in progress.
*/
private void tick() {
long elapsedMs = U.currentTimeMillis() - msStart;
final long totalCnt = overallRecordsProcessed.longValue();
long elapsedMsFromPrevTick = elapsedMs - prevMsElapsed.getAndSet(elapsedMs);
if (elapsedMsFromPrevTick == 0)
return;
final long currPutPerSec = ((totalCnt - prevRecordsCnt.getAndSet(totalCnt)) * 1000) / elapsedMsFromPrevTick;
final long averagePutPerSec = totalCnt * 1000 / elapsedMs;
boolean slowProgress = currPutPerSec < averagePutPerSec / 10 && !stopping;
final String fileNameWithDump = slowProgress ? reactNoProgress() : "";
DataStorageConfiguration dsCfg = ignite.configuration().getDataStorageConfiguration();
String defRegName = dsCfg.getDefaultDataRegionConfiguration().getName();
long dirtyPages = -1;
for (DataRegionMetrics m : ignite.dataRegionMetrics()) if (m.getName().equals(defRegName))
dirtyPages = m.getDirtyPages();
GridCacheSharedContext<Object, Object> cacheSctx = null;
PageMemoryImpl pageMemory = null;
try {
cacheSctx = ((IgniteEx) ignite).context().cache().context();
pageMemory = (PageMemoryImpl) cacheSctx.database().dataRegion(defRegName).pageMemory();
} catch (IgniteCheckedException e) {
e.printStackTrace();
}
long cpBufPages = 0;
GridCacheDatabaseSharedManager db = (GridCacheDatabaseSharedManager) (cacheSctx.database());
AtomicInteger wrPageCntr = db.getCheckpointer().currentProgress().writtenPagesCounter();
long cpWrittenPages = wrPageCntr == null ? 0 : wrPageCntr.get();
AtomicInteger syncedPagesCntr = db.getCheckpointer().currentProgress().syncedPagesCounter();
int cpSyncedPages = syncedPagesCntr == null ? 0 : syncedPagesCntr.get();
AtomicInteger evictedPagesCntr = db.getCheckpointer().currentProgress().evictedPagesCounter();
int cpEvictedPages = evictedPagesCntr == null ? 0 : evictedPagesCntr.get();
int pageSize = pageMemory == null ? 0 : pageMemory.pageSize();
String cpWriteSpeed = getMBytesPrintable(detectDelta(elapsedMsFromPrevTick, cpWrittenPages, prevCpWrittenPages) * pageSize);
String cpSyncSpeed = getMBytesPrintable(detectDelta(elapsedMsFromPrevTick, cpSyncedPages, prevCpSyncedPages) * pageSize);
String walSpeed = "";
long throttleParkTimeNanos = 0;
double curDirtyRatio = 0.0;
String targetDirtyRatioStr = "";
double closeToThrottle = 0.0;
long idx = -1;
long lastArchIdx = -1;
int walArchiveSegments = 0;
long walWorkSegments = 0;
long markDirtySpeed = 0;
long cpWriteSpeedInPages = 0;
long estWrAllSpeed = 0;
try {
if (pageMemory != null) {
cpBufPages = pageMemory.checkpointBufferPagesCount();
PagesWriteSpeedBasedThrottle throttle = U.field(pageMemory, "writeThrottle");
if (throttle != null) {
curDirtyRatio = throttle.getCurrDirtyRatio();
double targetDirtyRatio = throttle.getTargetDirtyRatio();
targetDirtyRatioStr = targetDirtyRatio < 0 ? "" : formatDbl(targetDirtyRatio);
closeToThrottle = throttle.throttleWeight();
throttleParkTimeNanos = throttle.throttleParkTime();
markDirtySpeed = throttle.getMarkDirtySpeed();
cpWriteSpeedInPages = throttle.getCpWriteSpeed();
estWrAllSpeed = throttle.getLastEstimatedSpeedForMarkAll();
if (estWrAllSpeed > 99_999)
estWrAllSpeed = 99_999;
}
}
FileWriteAheadLogManager wal = (FileWriteAheadLogManager) cacheSctx.wal();
idx = 0;
lastArchIdx = 0;
walArchiveSegments = wal.walArchiveSegments();
walWorkSegments = idx - lastArchIdx;
/* // uncomment when currentWritePointer is available
WALPointer ptr = wal.currentWritePointer();
WALPointer prevWalPtr = this.prevWalPtrRef.getAndSet(ptr);
if (prevWalPtr != null) {
long idxDiff = ptr.index() - prevWalPtr.index();
long offDiff = ptr.fileOffset() - prevWalPtr.fileOffset();
long bytesDiff = idxDiff * maxWalSegmentSize + offDiff;
long bytesPerSec = (bytesDiff * 1000) / elapsedMsFromPrevTick;
walSpeed = getMBytesPrintable(bytesPerSec);
} else
walSpeed = "0";
*/
walSpeed = "0";
} catch (Exception e) {
X.error(e.getClass().getSimpleName() + ":" + e.getMessage());
}
long elapsedSecs = elapsedMs / 1000;
X.println(" >> " + operation + " done: " + totalCnt + "/" + elapsedSecs + "s, " + "Cur. " + operation + " " + currPutPerSec + " recs/sec " + "cpWriteSpeed=" + cpWriteSpeed + " " + "cpSyncSpeed=" + cpSyncSpeed + " " + "walSpeed= " + walSpeed + " " + "walWorkSeg.=" + walWorkSegments + " " + "markDirtySpeed=" + markDirtySpeed + " " + "Avg. " + operation + " " + averagePutPerSec + " recs/sec, " + "dirtyP=" + dirtyPages + ", " + "cpWrittenP.=" + cpWrittenPages + ", " + "cpBufP.=" + cpBufPages + " " + "threshold=" + targetDirtyRatioStr + " " + "walIdx=" + idx + " " + "archWalIdx=" + lastArchIdx + " " + "walArchiveSegments=" + walArchiveSegments + " " + fileNameWithDump);
line(elapsedSecs, currPutPerSec, walSpeed, cpWriteSpeed, cpSyncSpeed, walWorkSegments, throttleParkTimeNanos, formatDbl(curDirtyRatio), targetDirtyRatioStr, formatDbl(closeToThrottle), markDirtySpeed, cpWriteSpeedInPages, estWrAllSpeed, averagePutPerSec, dirtyPages, cpWrittenPages, cpSyncedPages, cpEvictedPages, idx, lastArchIdx, walArchiveSegments);
}
use of org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMemoryImpl in project ignite by apache.
the class CheckpointBufferDeadlockTest method runDeadlockScenario.
/**
*/
private void runDeadlockScenario() throws Exception {
LogListener lsnr = LogListener.matches(s -> s.contains("AssertionError")).build();
log.registerListener(lsnr);
IgniteEx ig = startGrid(0);
ig.cluster().active(true);
GridCacheDatabaseSharedManager db = (GridCacheDatabaseSharedManager) ig.context().cache().context().database();
FilePageStoreManager pageStoreMgr = (FilePageStoreManager) ig.context().cache().context().pageStore();
final String cacheName = "single-part";
CacheConfiguration<Object, Object> cacheCfg = new CacheConfiguration<>().setName(cacheName).setAffinity(new RendezvousAffinityFunction(false, 1));
IgniteCache<Object, Object> singlePartCache = ig.getOrCreateCache(cacheCfg);
db.enableCheckpoints(false).get();
Thread.sleep(1_000);
try (IgniteDataStreamer<Object, Object> streamer = ig.dataStreamer(singlePartCache.getName())) {
int entries = MAX_SIZE / ENTRY_BYTE_CHUNK_SIZE / 4;
for (int i = 0; i < entries; i++) streamer.addData(i, new byte[ENTRY_BYTE_CHUNK_SIZE]);
streamer.flush();
}
slowCheckpointEnabled.set(true);
log.info(">>> Slow checkpoints enabled");
db.enableCheckpoints(true).get();
AtomicBoolean fail = new AtomicBoolean(false);
IgniteInternalFuture<Long> fut = GridTestUtils.runMultiThreadedAsync(new Runnable() {
@Override
public void run() {
int loops = 0;
while (!stop.get()) {
if (loops % 10 == 0 && loops > 0 && loops < 500 || loops % 500 == 0 && loops >= 500)
log.info("Successfully completed " + loops + " loops");
db.checkpointReadLock();
try {
Set<FullPageId> pickedPagesSet = new HashSet<>();
PageStore store = pageStoreMgr.getStore(CU.cacheId(cacheName), 0);
int pages = store.pages();
DataRegion region = db.dataRegion(DataStorageConfiguration.DFLT_DATA_REG_DEFAULT_NAME);
PageMemoryImpl pageMem = (PageMemoryImpl) region.pageMemory();
while (pickedPagesSet.size() < PAGES_TOUCHED_UNDER_CP_LOCK) {
int pageIdx = ThreadLocalRandom.current().nextInt(PAGES_TOUCHED_UNDER_CP_LOCK, pages - PAGES_TOUCHED_UNDER_CP_LOCK);
long pageId = PageIdUtils.pageId(0, PageIdAllocator.FLAG_DATA, pageIdx);
long page = pageMem.acquirePage(CU.cacheId(cacheName), pageId);
try {
// We do not know correct flag(FLAG_DATA or FLAG_AUX). Skip page if no luck.
if (pageId != PageIO.getPageId(page + PageMemoryImpl.PAGE_OVERHEAD))
continue;
} finally {
pageMem.releasePage(CU.cacheId(cacheName), pageId, page);
}
pickedPagesSet.add(new FullPageId(pageId, CU.cacheId(cacheName)));
}
List<FullPageId> pickedPages = new ArrayList<>(pickedPagesSet);
assertEquals(PAGES_TOUCHED_UNDER_CP_LOCK, pickedPages.size());
// Sort to avoid deadlocks on pages rw-locks.
pickedPages.sort(new Comparator<FullPageId>() {
@Override
public int compare(FullPageId o1, FullPageId o2) {
int cmp = Long.compare(o1.groupId(), o2.groupId());
if (cmp != 0)
return cmp;
return Long.compare(o1.effectivePageId(), o2.effectivePageId());
}
});
List<Long> readLockedPages = new ArrayList<>();
// Read lock many pages at once intentionally.
for (int i = 0; i < PAGES_TOUCHED_UNDER_CP_LOCK / 2; i++) {
FullPageId fpid = pickedPages.get(i);
long page = pageMem.acquirePage(fpid.groupId(), fpid.pageId());
long abs = pageMem.readLock(fpid.groupId(), fpid.pageId(), page);
assertFalse(fpid.toString(), abs == 0);
readLockedPages.add(page);
}
// Emulate writes to trigger throttling.
for (int i = PAGES_TOUCHED_UNDER_CP_LOCK / 2; i < PAGES_TOUCHED_UNDER_CP_LOCK && !stop.get(); i++) {
FullPageId fpid = pickedPages.get(i);
long page = pageMem.acquirePage(fpid.groupId(), fpid.pageId());
long abs = pageMem.writeLock(fpid.groupId(), fpid.pageId(), page);
assertFalse(fpid.toString(), abs == 0);
pageMem.writeUnlock(fpid.groupId(), fpid.pageId(), page, null, true);
pageMem.releasePage(fpid.groupId(), fpid.pageId(), page);
}
for (int i = 0; i < PAGES_TOUCHED_UNDER_CP_LOCK / 2; i++) {
FullPageId fpid = pickedPages.get(i);
pageMem.readUnlock(fpid.groupId(), fpid.pageId(), readLockedPages.get(i));
pageMem.releasePage(fpid.groupId(), fpid.pageId(), readLockedPages.get(i));
}
} catch (Throwable e) {
log.error("Error in loader thread", e);
fail.set(true);
} finally {
db.checkpointReadUnlock();
}
loops++;
}
}
}, 10, "load-runner");
// Await for the start of throttling.
Thread.sleep(10_000);
slowCheckpointEnabled.set(false);
log.info(">>> Slow checkpoints disabled");
assertFalse(fail.get());
// Previous checkpoint should eventually finish.
forceCheckpoint();
stop.set(true);
fut.get();
db.enableCheckpoints(true).get();
// check that there is no problem with pinned pages
ig.destroyCache(cacheName);
assertFalse(lsnr.check());
log.unregisterListener(lsnr);
}
use of org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMemoryImpl in project ignite by apache.
the class PageMemoryTracker method checkPages.
/**
* Checks if there are any differences between the Ignite's data regions content and pages inside the tracker.
*
* @param checkAll Check all tracked pages, otherwise check until first error.
* @param checkPageCnt Check tracked and allocated pages count. This check can be done only if there is no
* concurrent modification of pages in the system (for example when checkpointWriteLock is held). Some threads
* (for example MVCC vacuum cleaner) can modify pages even if there is no activity from a users point of view.
* @return {@code true} if content of all tracked pages equals to content of these pages in the ignite instance.
*/
private boolean checkPages(boolean checkAll, boolean checkPageCnt) throws IgniteCheckedException {
if (!started)
throw new IgniteCheckedException("Page memory checking only possible when tracker is started.");
GridCacheProcessor cacheProc = gridCtx.cache();
boolean res = true;
synchronized (pageAllocatorMux) {
long totalAllocated = pageStoreAllocatedPages();
log.info(">>> Total tracked pages: " + pages.size());
log.info(">>> Total allocated pages: " + totalAllocated);
dumpStats();
if (emptyPds && checkPageCnt && pages.size() != totalAllocated) {
res = false;
log.error("Started from empty PDS, but tracked pages count not equals to allocated pages count");
dumpPagesCountDiff();
if (!checkAll)
return false;
}
}
Set<Integer> groupsWarned = new HashSet<>();
for (DirectMemoryPage page : pages.values()) {
FullPageId fullPageId = page.fullPageId();
PageMemory pageMem;
if (fullPageId.groupId() == MetaStorage.METASTORAGE_CACHE_ID)
pageMem = cacheProc.context().database().metaStorage().pageMemory();
else if (fullPageId.groupId() == TxLog.TX_LOG_CACHE_ID)
pageMem = cacheProc.context().database().dataRegion(TxLog.TX_LOG_CACHE_NAME).pageMemory();
else {
CacheGroupContext ctx = cacheProc.cacheGroup(fullPageId.groupId());
if (ctx != null)
pageMem = ctx.dataRegion().pageMemory();
else {
if (!groupsWarned.contains(fullPageId.groupId())) {
log.warning("Cache group " + fullPageId.groupId() + " not found.");
groupsWarned.add(fullPageId.groupId());
}
continue;
}
}
assert pageMem instanceof PageMemoryImpl;
long rmtPage = pageMem.acquirePage(fullPageId.groupId(), fullPageId.pageId());
try {
long rmtPageAddr = pageMem.readLockForce(fullPageId.groupId(), fullPageId.pageId(), rmtPage);
try {
page.lock();
try {
if (rmtPageAddr == 0L) {
res = false;
log.error("Can't lock page: " + fullPageId);
dumpHistory(page);
} else if (!comparePages(fullPageId, page, rmtPageAddr))
res = false;
if (!res && !checkAll)
return false;
} finally {
page.unlock();
}
} finally {
if (rmtPageAddr != 0L)
pageMem.readUnlock(fullPageId.groupId(), fullPageId.pageId(), rmtPage);
}
} finally {
pageMem.releasePage(fullPageId.groupId(), fullPageId.pageId(), rmtPage);
}
}
return res;
}
Aggregations