Skip to content

Commit fd6e15d

Browse files
IGNITE-20697 Store crash recovery data to checkpoint recovery files - Fixes #11024.
Signed-off-by: Aleksey Plekhanov <[email protected]>
1 parent 1bd8c8a commit fd6e15d

File tree

63 files changed

+2458
-358
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+2458
-358
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.ignite.internal.processors.cache.persistence.db;
19+
20+
import org.apache.ignite.configuration.DiskPageCompression;
21+
22+
/**
23+
* Class containing tests for applying checkpoint recovery data with compression.
24+
*/
25+
public class IgnitePdsCheckpointRecoveryWithCompressionTest extends IgnitePdsCheckpointRecoveryTest {
26+
/** */
27+
@Override protected DiskPageCompression getCompression() {
28+
return DiskPageCompression.SNAPPY;
29+
}
30+
}

modules/compress/src/test/java/org/apache/ignite/testsuites/IgnitePdsCompressionTestSuite.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.ArrayList;
2121
import java.util.Arrays;
2222
import java.util.List;
23+
import org.apache.ignite.internal.processors.cache.persistence.db.IgnitePdsCheckpointRecoveryWithCompressionTest;
2324
import org.apache.ignite.internal.processors.cache.persistence.db.wal.IgnitePdsCheckpointSimulationWithRealCpDisabledAndWalCompressionTest;
2425
import org.apache.ignite.internal.processors.cache.persistence.db.wal.WalCompactionAndPageCompressionTest;
2526
import org.apache.ignite.internal.processors.cache.persistence.db.wal.WalRecoveryWithPageCompressionAndTdeTest;
@@ -64,6 +65,9 @@ public static List<Class<?>> suite() {
6465
suite.add(IgnitePdsCheckpointSimulationWithRealCpDisabledAndWalCompressionTest.class);
6566
suite.add(WalCompactionAndPageCompressionTest.class);
6667

68+
// Checkpoint recovery.
69+
suite.add(IgnitePdsCheckpointRecoveryWithCompressionTest.class);
70+
6771
// Snapshots.
6872
suite.add(SnapshotCompressionBasicTest.class);
6973

modules/core/src/main/java/org/apache/ignite/configuration/DataStorageConfiguration.java

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,12 @@ public class DataStorageConfiguration implements Serializable {
187187
/** Value used to indicate the use of half of the {@link #getMaxWalArchiveSize}. */
188188
public static final long HALF_MAX_WAL_ARCHIVE_SIZE = -1;
189189

190+
/** Default value for {@link #writeRecoveryDataOnCheckpoint} property. */
191+
public static final boolean DFLT_WRITE_RECOVERY_DATA_ON_CP = false;
192+
193+
/** Default compression algorithm for checkpoint recovery data. */
194+
public static final DiskPageCompression DFLT_CP_RECOVERY_DATA_COMRESSION = DiskPageCompression.SKIP_GARBAGE;
195+
190196
/** Memory page size. */
191197
private int pageSize = IgniteSystemProperties.getInteger(
192198
IGNITE_DEFAULT_DATA_STORAGE_PAGE_SIZE, 0);
@@ -339,6 +345,19 @@ public class DataStorageConfiguration implements Serializable {
339345
/** Default memory allocator for all data regions. */
340346
@Nullable private MemoryAllocator memoryAllocator = null;
341347

348+
/**
349+
* Mode for storing page recovery data.
350+
* If {@code true}, page recovery data will be written during checkpoint.
351+
* If {@code false}, WAL physical records will be used to store page recovery data.
352+
*/
353+
private boolean writeRecoveryDataOnCheckpoint = DFLT_WRITE_RECOVERY_DATA_ON_CP;
354+
355+
/** Compression algorithm for checkpoint recovery data. */
356+
private DiskPageCompression cpRecoveryDataCompression = DFLT_CP_RECOVERY_DATA_COMRESSION;
357+
358+
/** Compression level for checkpoint recovery data. */
359+
private Integer cpRecoveryDataCompressionLevel;
360+
342361
/**
343362
* Creates valid durable memory configuration with all default values.
344363
*/
@@ -1394,6 +1413,72 @@ public DataStorageConfiguration setMemoryAllocator(MemoryAllocator allocator) {
13941413
return this;
13951414
}
13961415

1416+
/**
1417+
* @return Flag defining mode for storing page recovery data. If {@code true}, recovery data will be written
1418+
* during checkpoint, if {@code false}, WAL physical records will be used to store recovery data.
1419+
*/
1420+
public boolean isWriteRecoveryDataOnCheckpoint() {
1421+
return writeRecoveryDataOnCheckpoint;
1422+
}
1423+
1424+
/**
1425+
* Sets mode for storing page recovery data.
1426+
*
1427+
* @param writeRecoveryDataOnCheckpoint If {@code true}, page recovery data will be written during checkpoint,
1428+
* if {@code false}, WAL physical records will be used to store page recovery data.
1429+
* Default is {@link #DFLT_WRITE_RECOVERY_DATA_ON_CP}.
1430+
* @return {@code this} for chaining.
1431+
*/
1432+
public DataStorageConfiguration setWriteRecoveryDataOnCheckpoint(boolean writeRecoveryDataOnCheckpoint) {
1433+
this.writeRecoveryDataOnCheckpoint = writeRecoveryDataOnCheckpoint;
1434+
1435+
return this;
1436+
}
1437+
1438+
/**
1439+
* Gets compression algorithm for checkpoint recovery data.
1440+
*
1441+
* @return Page compression algorithm.
1442+
*/
1443+
public DiskPageCompression getCheckpointRecoveryDataCompression() {
1444+
return cpRecoveryDataCompression == null ? DFLT_CP_RECOVERY_DATA_COMRESSION : cpRecoveryDataCompression;
1445+
}
1446+
1447+
/**
1448+
* Sets compression algorithm for checkpoint recovery data.
1449+
*
1450+
* @param cpRecoveryDataCompression Compression algorithm.
1451+
* @return {@code this} for chaining.
1452+
*/
1453+
public DataStorageConfiguration setCheckpointRecoveryDataCompression(DiskPageCompression cpRecoveryDataCompression) {
1454+
this.cpRecoveryDataCompression = cpRecoveryDataCompression;
1455+
1456+
return this;
1457+
}
1458+
1459+
/**
1460+
* Gets {@link #getCheckpointRecoveryDataCompression()} algorithm specific compression level.
1461+
*
1462+
* @return Checkpoint recovery data compression level or {@code null} for default.
1463+
*/
1464+
public Integer getCheckpointRecoveryDataCompressionLevel() {
1465+
return cpRecoveryDataCompressionLevel;
1466+
}
1467+
1468+
/**
1469+
* Sets {@link #setCheckpointRecoveryDataCompression(DiskPageCompression)} algorithm specific compression level.
1470+
*
1471+
* @param cpRecoveryDataCompressionLevel Checkpoint recovery data compression level or {@code null} to use default.
1472+
* {@link DiskPageCompression#ZSTD Zstd}: from {@code -131072} to {@code 22} (default {@code 3}).
1473+
* {@link DiskPageCompression#LZ4 LZ4}: from {@code 0} to {@code 17} (default {@code 0}).
1474+
* @return {@code this} for chaining.
1475+
*/
1476+
public DataStorageConfiguration setCheckpointRecoveryDataCompressionLevel(Integer cpRecoveryDataCompressionLevel) {
1477+
this.cpRecoveryDataCompressionLevel = cpRecoveryDataCompressionLevel;
1478+
1479+
return this;
1480+
}
1481+
13971482
/** {@inheritDoc} */
13981483
@Override public String toString() {
13991484
return S.toString(DataStorageConfiguration.class, this);

modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1563,13 +1563,15 @@ private long requiredOffheap() {
15631563
for (DataRegionConfiguration dataReg : dataRegions) {
15641564
res += dataReg.getMaxSize();
15651565

1566-
res += U.checkpointBufferSize(dataReg);
1566+
res += U.checkpointBufferSize(memCfg, dataReg);
15671567
}
15681568
}
15691569

1570-
res += memCfg.getDefaultDataRegionConfiguration().getMaxSize();
1570+
DataRegionConfiguration dfltDataRegion = memCfg.getDefaultDataRegionConfiguration();
15711571

1572-
res += U.checkpointBufferSize(memCfg.getDefaultDataRegionConfiguration());
1572+
res += dfltDataRegion.getMaxSize();
1573+
1574+
res += U.checkpointBufferSize(memCfg, dfltDataRegion);
15731575

15741576
return res;
15751577
}

modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/IgniteWriteAheadLogManager.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,12 +208,12 @@ public WALIterator replay(
208208
public int reserved(WALPointer low, WALPointer high);
209209

210210
/**
211-
* Checks WAL disabled for cache group.
211+
* Checks WAL page records disabled.
212212
*
213213
* @param grpId Group id.
214214
* @param pageId Page id.
215215
*/
216-
public boolean disabled(int grpId, long pageId);
216+
public boolean pageRecordsDisabled(int grpId, long pageId);
217217

218218
/**
219219
* Getting local WAL segment size.

modules/core/src/main/java/org/apache/ignite/internal/processors/cache/WalStateManager.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,13 +1012,16 @@ private WalStateResult awaitCheckpoint(CheckpointProgress cpFut, WalStatePropose
10121012
}
10131013

10141014
/**
1015-
* Checks WAL disabled for cache group.
1015+
* Checks WAL page records disabled.
10161016
*
10171017
* @param grpId Group id.
10181018
* @param pageId Page id.
10191019
* @return {@code True} if WAL disable for group. {@code False} If not.
10201020
*/
1021-
public boolean isDisabled(int grpId, long pageId) {
1021+
public boolean isPageRecordsDisabled(int grpId, long pageId) {
1022+
if (cctx.kernalContext().config().getDataStorageConfiguration().isWriteRecoveryDataOnCheckpoint())
1023+
return true;
1024+
10221025
CacheGroupContext ctx = cctx.cache().cacheGroup(grpId);
10231026

10241027
return ctx != null && (!ctx.walEnabled()

modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStorageMetricsImpl.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ public class DataStorageMetricsImpl {
8989
/** */
9090
private final AtomicLongMetric lastCpSplitAndSortPagesDuration;
9191

92+
/** */
93+
private final AtomicLongMetric lastCpRecoveryDataWriteDuration;
94+
95+
/** */
96+
private final AtomicLongMetric lastCpRecoveryDataSize;
97+
9298
/** */
9399
private final AtomicLongMetric lastCpTotalPages;
94100

@@ -155,6 +161,9 @@ public class DataStorageMetricsImpl {
155161
/** */
156162
private final HistogramMetricImpl cpSplitAndSortPagesHistogram;
157163

164+
/** */
165+
private final HistogramMetricImpl cpRecoveryDataWriteHistogram;
166+
158167
/** */
159168
private final HistogramMetricImpl cpHistogram;
160169

@@ -246,6 +255,12 @@ public DataStorageMetricsImpl(
246255
lastCpSplitAndSortPagesDuration = mreg.longMetric("LastCheckpointSplitAndSortPagesDuration",
247256
"Duration of splitting and sorting checkpoint pages of the last checkpoint in milliseconds.");
248257

258+
lastCpRecoveryDataWriteDuration = mreg.longMetric("LastCheckpointRecoveryDataWriteDuration",
259+
"Duration of checkpoint recovery data write in milliseconds.");
260+
261+
lastCpRecoveryDataSize = mreg.longMetric("LastCheckpointRecoveryDataSize",
262+
"Size of checkpoint recovery data in bytes.");
263+
249264
lastCpTotalPages = mreg.longMetric("LastCheckpointTotalPagesNumber",
250265
"Total number of pages written during the last checkpoint.");
251266

@@ -312,6 +327,9 @@ public DataStorageMetricsImpl(
312327
cpSplitAndSortPagesHistogram = mreg.histogram("CheckpointSplitAndSortPagesHistogram", cpBounds,
313328
"Histogram of splitting and sorting checkpoint pages duration in milliseconds.");
314329

330+
cpRecoveryDataWriteHistogram = mreg.histogram("CheckpointRecoveryDataWriteHistogram", cpBounds,
331+
"Histogram of checkpoint recovery data write duration in milliseconds.");
332+
315333
cpHistogram = mreg.histogram("CheckpointHistogram", cpBounds,
316334
"Histogram of checkpoint duration in milliseconds.");
317335

@@ -672,11 +690,13 @@ public boolean metricsEnabled() {
672690
* @param walRecordFsyncDuration Duration of WAL fsync after logging {@link CheckpointRecord} on checkpoint begin.
673691
* @param writeEntryDuration Duration of checkpoint entry buffer writing to file.
674692
* @param splitAndSortPagesDuration Duration of splitting and sorting checkpoint pages.
693+
* @param recoveryDataWriteDuration Recovery data write duration.
675694
* @param duration Total checkpoint duration.
676695
* @param start Checkpoint start time.
677696
* @param totalPages Total number of all pages in checkpoint.
678697
* @param dataPages Total number of data pages in checkpoint.
679698
* @param cowPages Total number of COW-ed pages in checkpoint.
699+
* @param recoveryDataSize Recovery data size, in bytes.
680700
* @param storageSize Storage space allocated, in bytes.
681701
* @param sparseStorageSize Storage space allocated adjusted for possible sparsity, in bytes.
682702
*/
@@ -691,11 +711,13 @@ public void onCheckpoint(
691711
long walRecordFsyncDuration,
692712
long writeEntryDuration,
693713
long splitAndSortPagesDuration,
714+
long recoveryDataWriteDuration,
694715
long duration,
695716
long start,
696717
long totalPages,
697718
long dataPages,
698719
long cowPages,
720+
long recoveryDataSize,
699721
long storageSize,
700722
long sparseStorageSize
701723
) {
@@ -712,11 +734,13 @@ public void onCheckpoint(
712734
lastCpWalRecordFsyncDuration.value(walRecordFsyncDuration);
713735
lastCpWriteEntryDuration.value(writeEntryDuration);
714736
lastCpSplitAndSortPagesDuration.value(splitAndSortPagesDuration);
737+
lastCpRecoveryDataWriteDuration.value(recoveryDataWriteDuration);
715738
lastCpDuration.value(duration);
716739
lastCpStart.value(start);
717740
lastCpTotalPages.value(totalPages);
718741
lastCpDataPages.value(dataPages);
719742
lastCpCowPages.value(cowPages);
743+
lastCpRecoveryDataSize.value(recoveryDataSize);
720744
this.storageSize.value(storageSize);
721745
this.sparseStorageSize.value(sparseStorageSize);
722746

@@ -732,6 +756,7 @@ public void onCheckpoint(
732756
cpWalRecordFsyncHistogram.value(walRecordFsyncDuration);
733757
cpWriteEntryHistogram.value(writeEntryDuration);
734758
cpSplitAndSortPagesHistogram.value(splitAndSortPagesDuration);
759+
cpRecoveryDataWriteHistogram.value(recoveryDataWriteDuration);
735760
cpHistogram.value(duration);
736761
}
737762

0 commit comments

Comments
 (0)