/** {@inheritDoc} */ @Override public void releaseHistoryForPreloading() { for (Map.Entry<T2<Integer, Integer>, T2<Long, WALPointer>> e : reservedForPreloading.entrySet()) { try { cctx.wal().release(e.getValue().get2()); } catch (IgniteCheckedException ex) { U.error(log, "Could not release WAL reservation", ex); throw new IgniteException(ex); } } reservedForPreloading.clear(); }
/** */ public MetaStorage( GridCacheSharedContext<?, ?> cctx, DataRegion dataRegion, DataRegionMetricsImpl regionMetrics, boolean readOnly ) { this.cctx = cctx; wal = cctx.wal(); this.dataRegion = dataRegion; this.regionMetrics = regionMetrics; this.readOnly = readOnly; log = cctx.logger(getClass()); this.failureProcessor = cctx.kernalContext().failure(); }
/** {@inheritDoc} */ @Override public boolean reserveHistoryForPreloading(int grpId, int partId, long cntr) { CheckpointEntry cpEntry = cpHistory.searchCheckpointEntry(grpId, partId, cntr); if (cpEntry == null) return false; WALPointer ptr = cpEntry.checkpointMark(); if (ptr == null) return false; boolean reserved = cctx.wal().reserve(ptr); if (reserved) reservedForPreloading.put(new T2<>(grpId, partId), new T2<>(cntr, ptr)); return reserved; }
/** * Calculates tail pointer for WAL at the end of logical recovery. * * @param from Start replay WAL from. * @return Tail pointer. * @throws IgniteCheckedException If failed. */ private WALPointer tailPointer(WALPointer from) throws IgniteCheckedException { WALIterator it = cctx.wal().replay(from); try { while (it.hasNextX()) { IgniteBiTuple<WALPointer, WALRecord> rec = it.nextX(); if (rec == null) break; } } finally { it.close(); } return it.lastRead().map(WALPointer::next).orElse(null); }
/** * Calculate mark until delete by maximum allowed archive size. * * @return Checkpoint mark until which checkpoints can be deleted(not including this pointer). */ @Nullable private WALPointer checkpointMarkUntilDeleteByArchiveSize() { long absFileIdxToDel = cctx.wal().maxArchivedSegmentToDelete(); if (absFileIdxToDel < 0) return null; long fileUntilDel = absFileIdxToDel + 1; long checkpointFileIdx = absFileIdx(lastCheckpoint()); for (CheckpointEntry cpEntry : histMap.values()) { long currFileIdx = absFileIdx(cpEntry); if (checkpointFileIdx <= currFileIdx || fileUntilDel <= currFileIdx) return cpEntry.checkpointMark(); } return lastCheckpoint().checkpointMark(); }
/** * For testing purposes only. * @param toState State to set. */ public void setState(GridDhtPartitionState toState) { if (grp.persistenceEnabled() && grp.walEnabled()) { synchronized (this) { long state0 = state.get(); this.state.compareAndSet(state0, setPartState(state0, toState)); try { ctx.wal().log(new PartitionMetaStateRecord(grp.groupId(), id, toState, updateCounter())); } catch (IgniteCheckedException e) { U.error(log, "Error while writing to log", e); } } } else restoreState(toState); }
/** * Extract IgniteWriteAheadLogManager. */ private IgniteWriteAheadLogManager wal(Ignite ignite) { return ((IgniteEx)ignite).context().cache().context().wal(); } }
/** {@inheritDoc} */ @Nullable @Override protected Collection<String> run(@Nullable VisorWalTaskArg arg) throws IgniteException { try { GridKernalContext cctx = ignite.context(); GridCacheDatabaseSharedManager dbMgr = (GridCacheDatabaseSharedManager)cctx.cache().context().database(); FileWriteAheadLogManager wal = (FileWriteAheadLogManager)cctx.cache().context().wal(); if (dbMgr == null || arg == null || wal == null) return null; switch (arg.getOperation()) { case DELETE_UNUSED_WAL_SEGMENTS: return deleteUnusedWalSegments(dbMgr, wal); case PRINT_UNUSED_WAL_SEGMENTS: default: return getUnusedWalSegments(dbMgr, wal); } } catch (IgniteCheckedException e){ U.error(log, "Failed to perform WAL task", e); throw new IgniteException("Failed to perform WAL task", e); } }
/** * Logs and clears checkpoint history after checkpoint finish. * * @return List of checkpoints removed from history. */ public List<CheckpointEntry> onCheckpointFinished(Checkpoint chp, boolean truncateWal) { chp.walSegsCoveredRange(calculateWalSegmentsCovered()); WALPointer checkpointMarkUntilDel = isWalHistorySizeParameterEnabled //check for compatibility mode. ? checkpointMarkUntilDeleteByMemorySize() : newerPointer(checkpointMarkUntilDeleteByMemorySize(), checkpointMarkUntilDeleteByArchiveSize()); if (checkpointMarkUntilDel == null) return Collections.emptyList(); List<CheckpointEntry> deletedCheckpoints = onWalTruncated(checkpointMarkUntilDel); int deleted = 0; if (truncateWal) deleted += cctx.wal().truncate(null, firstCheckpointPointer()); chp.walFilesDeleted(deleted); return deletedCheckpoints; }
/** * @return {@code true} if reserve list is empty. */ private boolean isReserveListEmpty(IgniteEx ig) { FileWriteAheadLogManager wal = (FileWriteAheadLogManager)ig.context().cache().context().wal(); Object segmentAware = GridTestUtils.getFieldValue(wal, "segmentAware"); synchronized (segmentAware) { Map reserved = GridTestUtils.getFieldValue(GridTestUtils.getFieldValue(segmentAware, "reservationStorage"), "reserved"); if (reserved.isEmpty()) return true; } return false; }
/** * Invalidates page memory for given partition. Destroys partition store. * <b>NOTE:</b> This method can be invoked only within checkpoint lock or checkpointer thread. * * @param grpId Group ID. * @param partId Partition ID. * * @throws IgniteCheckedException If destroy has failed. */ public void destroyPartitionStore(int grpId, int partId) throws IgniteCheckedException { PageMemoryEx pageMemory = (PageMemoryEx)grp.dataRegion().pageMemory(); int tag = pageMemory.invalidate(grp.groupId(), partId); if (grp.walEnabled()) ctx.wal().log(new PartitionDestroyRecord(grp.groupId(), partId)); ctx.pageStore().onPartitionDestroyed(grpId, partId, tag); }
/** {@inheritDoc} */ @Override public Boolean run(int cacheId, long pageId, long page, long pageAddr, PageIO io, Boolean walPlc, MvccVersion newVer, int itemId, IoStatisticsHolder statHolder) throws IgniteCheckedException { assert grp.mvccEnabled(); DataPageIO iox = (DataPageIO)io; int off = iox.getPayloadOffset(pageAddr, itemId, grp.dataRegion().pageMemory().realPageSize(grp.groupId()), MVCC_INFO_SIZE); long newCrd = iox.newMvccCoordinator(pageAddr, off); long newCntr = iox.newMvccCounter(pageAddr, off); int newOpCntr = iox.newMvccOperationCounter(pageAddr, off); assert newCrd == MVCC_CRD_COUNTER_NA || state(grp, newCrd, newCntr, newOpCntr) == TxState.ABORTED; iox.updateNewVersion(pageAddr, off, newVer, TxState.NA); if (isWalDeltaRecordNeeded(grp.dataRegion().pageMemory(), cacheId, pageId, page, ctx.wal(), walPlc)) ctx.wal().log(new DataPageMvccMarkUpdatedRecord(cacheId, pageId, itemId, newVer.coordinatorVersion(), newVer.counter(), newVer.operationCounter())); return TRUE; } }
/** * @param cacheId ID of cache initiated counter update. * @param topVer Topology version for current operation. * @return Next update index. */ public long nextUpdateCounter(int cacheId, AffinityTopologyVersion topVer, boolean primary, @Nullable Long primaryCntr) { long nextCntr = store.nextUpdateCounter(); if (grp.sharedGroup()) grp.onPartitionCounterUpdate(cacheId, id, primaryCntr != null ? primaryCntr : nextCntr, topVer, primary); // This is first update in partition, we should log partition state information for further crash recovery. if (nextCntr == 1) { if (grp.persistenceEnabled() && grp.walEnabled()) try { ctx.wal().log(new PartitionMetaStateRecord(grp.groupId(), id, state(), 0)); } catch (IgniteCheckedException e) { U.error(log, "Failed to log partition state snapshot to WAL.", e); ctx.kernalContext().failure().process(new FailureContext(FailureType.CRITICAL_ERROR, e)); } } return nextCntr; }
/** * @throws Exception If failed. */ @Test public void testWALManagerIterator() throws Exception { IgniteEx ig = grid(); IgniteWriteAheadLogManager wal = ig.context().cache().context().wal(); doTest(wal, wal.replay(null)); }
/** * @throws Exception If failed. */ @Test public void testStandAloneIterator() throws Exception { IgniteEx ig = grid(); IgniteWriteAheadLogManager wal = ig.context().cache().context().wal(); File walArchiveDir = U.field(wal, "walArchiveDir"); IgniteWalIteratorFactory iteratorFactory = new IgniteWalIteratorFactory(); doTest(wal, iteratorFactory.iterator(walArchiveDir)); }
/** * @throws Exception If failed. */ private void failFormatFileOnClusterActivate() throws Exception { failMtdNameRef.set(null); startGrid(0); startGrid(1); if (!fsync) { setFileIOFactory(grid(0).context().cache().context().wal()); setFileIOFactory(grid(1).context().cache().context().wal()); } failMtdNameRef.set(formatFile); grid(0).cluster().active(true); checkCause(failureHandler(0).awaitFailure(2000).error()); checkCause(failureHandler(1).awaitFailure(2000).error()); }
/** */ @Test public void test() throws Exception { IgniteEx ig = startGrid(0); ig.cluster().active(true); ig.context().cache().context().database().checkpointReadLock(); try { ig.context().cache().context().wal().log(new RolloverRecord()); } finally { ig.context().cache().context().database().checkpointReadUnlock(); } } }
/** */ private void checkNextSegmentType(WALMode mode, boolean disableArch) throws Exception { walMode = mode; disableWALArchiving = disableArch; IgniteEx ig = startGrid(0); ig.cluster().active(true); IgniteWriteAheadLogManager walMgr = ig.context().cache().context().wal(); ig.context().cache().context().database().checkpointReadLock(); try { WALPointer ptr = walMgr.log(new AdHocWALRecord(), NEXT_SEGMENT); assertEquals(1, ((FileWALPointer)ptr).index()); } finally { ig.context().cache().context().database().checkpointReadUnlock(); } }
/** */ private void checkCurrentSegmentType(WALMode mode, boolean disableArch) throws Exception { walMode = mode; disableWALArchiving = disableArch; IgniteEx ig = startGrid(0); ig.cluster().active(true); IgniteWriteAheadLogManager walMgr = ig.context().cache().context().wal(); ig.context().cache().context().database().checkpointReadLock(); try { WALPointer ptr = walMgr.log(new AdHocWALRecord(), CURRENT_SEGMENT); assertEquals(0, ((FileWALPointer)ptr).index()); } finally { ig.context().cache().context().database().checkpointReadUnlock(); } }
/** * Tests that grid cache manager correctly truncates unused WAL segments; * * @throws Exception if failed. */ @Test public void testWalDoesNotTruncatedWhenSegmentReserved() throws Exception { IgniteEx ig0 = prepareGrid(4); GridCacheDatabaseSharedManager dbMgr = (GridCacheDatabaseSharedManager)ig0.context().cache().context() .database(); IgniteWriteAheadLogManager wal = ig0.context().cache().context().wal(); long resIdx = getReservedWalSegmentIndex(dbMgr); assertTrue("Expected that at least resIdx greater than 0, real is " + resIdx, resIdx > 0); FileWALPointer lowPtr = (FileWALPointer) dbMgr.checkpointHistory().firstCheckpointPointer(); assertTrue("Expected that dbMbr returns valid resIdx", lowPtr.index() == resIdx); // Reserve previous WAL segment. wal.reserve(new FileWALPointer(resIdx - 1, 0, 0)); int numDel = wal.truncate(null, lowPtr); int expNumDel = (int)resIdx - 1; assertTrue("Expected del segments is " + expNumDel + ", real is " + numDel, expNumDel == numDel); }