From 57f43d101d270a4855af9048af69fe8d49112d66 Mon Sep 17 00:00:00 2001 From: Chris Vest Date: Thu, 30 Nov 2017 15:22:19 +0100 Subject: [PATCH] Add rudementary volumetric check-point triggering. Currently it only *starts* a check-point process as soon as it looks like there are logs that could be pruned. In the future it would be interesting to have it use statistics to try to predict the frequency at which log prunings happen, and adjust the check-point frequency to match. --- .../factory/GraphDatabaseSettings.java | 9 +- .../org/neo4j/kernel/NeoStoreDataSource.java | 2 +- .../AbstractCheckPointThreshold.java | 2 +- .../log/checkpoint/CheckPointThreshold.java | 6 +- .../checkpoint/CheckPointThresholdPolicy.java | 9 +- .../ContinuousCheckPointThreshold.java | 2 +- .../checkpoint/ContinuousThresholdPolicy.java | 4 +- .../CountCommittedTransactionThreshold.java | 2 +- .../checkpoint/PeriodicThresholdPolicy.java | 4 +- .../checkpoint/TimeCheckPointThreshold.java | 2 +- .../transaction/log/pruning/LogPruning.java | 14 +++ .../checkpoint/CheckPointThresholdTest.java | 70 +------------ .../CheckPointThresholdTestSupport.java | 98 +++++++++++++++++++ .../VolumetricCheckPointPolicy.java | 45 +++++++++ .../VolumetricCheckPointThreshold.java | 50 ++++++++++ ...n.log.checkpoint.CheckPointThresholdPolicy | 1 + .../VolumetricCheckPointThresholdTest.java | 80 +++++++++++++++ 17 files changed, 316 insertions(+), 84 deletions(-) create mode 100644 community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/checkpoint/CheckPointThresholdTestSupport.java create mode 100644 enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/transaction/log/checkpoint/VolumetricCheckPointPolicy.java create mode 100644 enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/transaction/log/checkpoint/VolumetricCheckPointThreshold.java create mode 100644 enterprise/kernel/src/main/resources/META-INF/services/org.neo4j.kernel.impl.transaction.log.checkpoint.CheckPointThresholdPolicy create mode 100644 enterprise/kernel/src/test/java/org/neo4j/kernel/impl/enterprise/transaction/log/checkpoint/VolumetricCheckPointThresholdTest.java diff --git a/community/kernel/src/main/java/org/neo4j/graphdb/factory/GraphDatabaseSettings.java b/community/kernel/src/main/java/org/neo4j/graphdb/factory/GraphDatabaseSettings.java index 13a7de836eb64..aa25a77b595c8 100644 --- a/community/kernel/src/main/java/org/neo4j/graphdb/factory/GraphDatabaseSettings.java +++ b/community/kernel/src/main/java/org/neo4j/graphdb/factory/GraphDatabaseSettings.java @@ -344,8 +344,13 @@ public class GraphDatabaseSettings implements LoadableConfig @Description( "Configures the general policy for when check-points should occur. The default policy is to " + "check-point 'periodically', as specified by the 'dbms.checkpoint.interval.tx' and " + "'dbms.checkpoint.interval.time' settings. " + - "An alternative policy is to check-point 'continuously', which will ignore those settings and run " + - "the check-point process all the time." ) + "There are two alternative policies: " + + "The first is to check-point 'continuously', which will ignore those settings and run the " + + "check-point process all the time. " + + "The second (Enterprise only) alternative policy is the 'volumetric' policy, which makes a " + + "best-effort at check-pointing often enough so that the database doesn't get too far behind on " + + "deleting old transaction logs in accordance with the 'dbms.tx_log.rotation.retention_policy' " + + "setting." ) public static final Setting check_point_policy = setting( "dbms.checkpoint", STRING, "periodically" ); @Description( "Configures the transaction interval between check-points. The database will not check-point more " + diff --git a/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java b/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java index a257130df0c34..0f69ce59d990f 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java @@ -642,7 +642,7 @@ private NeoStoreTransactionLogModule buildTransactionLogs( final LogicalTransactionStore logicalTransactionStore = new PhysicalLogicalTransactionStore( logFile, transactionMetadataCache, logEntryReader ); - CheckPointThreshold threshold = CheckPointThreshold.createThreshold( config, clock, logProvider ); + CheckPointThreshold threshold = CheckPointThreshold.createThreshold( config, clock, logPruning, logProvider ); final CheckPointerImpl checkPointer = new CheckPointerImpl( transactionIdStore, threshold, storageEngine, logPruning, appender, databaseHealth, logProvider, diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/AbstractCheckPointThreshold.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/AbstractCheckPointThreshold.java index 7e614f42f31e4..0928d5cb84d79 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/AbstractCheckPointThreshold.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/AbstractCheckPointThreshold.java @@ -26,7 +26,7 @@ * Abstract class that implement common logic for making the consumer to consume the description of this * threshold if {@link #thresholdReached(long)} is true. */ -abstract class AbstractCheckPointThreshold implements CheckPointThreshold +public abstract class AbstractCheckPointThreshold implements CheckPointThreshold { private final String description; diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/CheckPointThreshold.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/CheckPointThreshold.java index fdc5121b8e8e7..1b33e60b034a3 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/CheckPointThreshold.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/CheckPointThreshold.java @@ -26,6 +26,7 @@ import java.util.stream.Stream; import org.neo4j.kernel.configuration.Config; +import org.neo4j.kernel.impl.transaction.log.pruning.LogPruning; import org.neo4j.logging.LogProvider; import static org.neo4j.graphdb.factory.GraphDatabaseSettings.check_point_policy; @@ -78,7 +79,8 @@ public interface CheckPointThreshold /** * Create and configure a {@link CheckPointThreshold} based on the given configurations. */ - static CheckPointThreshold createThreshold( Config config, Clock clock, LogProvider logProvider ) + static CheckPointThreshold createThreshold( + Config config, Clock clock, LogPruning logPruning, LogProvider logProvider ) { String policyName = config.get( check_point_policy ); CheckPointThresholdPolicy policy; @@ -93,7 +95,7 @@ static CheckPointThreshold createThreshold( Config config, Clock clock, LogProvi "Using default policy instead.", e ); policy = new PeriodicThresholdPolicy(); } - return policy.createThreshold( config, clock, logProvider ); + return policy.createThreshold( config, clock, logPruning, logProvider ); } /** diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/CheckPointThresholdPolicy.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/CheckPointThresholdPolicy.java index e74330afe4949..be9d1b8a86665 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/CheckPointThresholdPolicy.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/CheckPointThresholdPolicy.java @@ -24,6 +24,7 @@ import org.neo4j.helpers.Service; import org.neo4j.kernel.configuration.Config; +import org.neo4j.kernel.impl.transaction.log.pruning.LogPruning; import org.neo4j.logging.LogProvider; /** @@ -32,8 +33,8 @@ * * The is determined by the {@link org.neo4j.graphdb.factory.GraphDatabaseSettings#check_point_policy} setting, and * based on this, the concrete policies are loaded and used to - * {@link CheckPointThreshold#createThreshold(Config, Clock, org.neo4j.logging.LogProvider) create} the final and fully configured check point - * thresholds. + * {@link CheckPointThreshold#createThreshold(Config, Clock, LogPruning, LogProvider) create} the final and fully + * configured check point thresholds. */ public abstract class CheckPointThresholdPolicy extends Service { @@ -62,6 +63,6 @@ public static CheckPointThresholdPolicy loadPolicy( String policyName ) throws N /** * Create a {@link CheckPointThreshold} instance based on this policy and the given configurations. */ - public abstract CheckPointThreshold createThreshold( Config config, Clock clock, - LogProvider logProvider ); + public abstract CheckPointThreshold createThreshold( + Config config, Clock clock, LogPruning logPruning, LogProvider logProvider ); } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/ContinuousCheckPointThreshold.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/ContinuousCheckPointThreshold.java index ffab742ca718d..b0236729684f7 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/ContinuousCheckPointThreshold.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/ContinuousCheckPointThreshold.java @@ -23,7 +23,7 @@ class ContinuousCheckPointThreshold extends AbstractCheckPointThreshold { - public ContinuousCheckPointThreshold() + ContinuousCheckPointThreshold() { super( "continuous threshold" ); } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/ContinuousThresholdPolicy.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/ContinuousThresholdPolicy.java index f6e3221f01551..b9a08ebd1a5fa 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/ContinuousThresholdPolicy.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/ContinuousThresholdPolicy.java @@ -23,6 +23,7 @@ import org.neo4j.helpers.Service; import org.neo4j.kernel.configuration.Config; +import org.neo4j.kernel.impl.transaction.log.pruning.LogPruning; import org.neo4j.logging.LogProvider; @Service.Implementation( CheckPointThresholdPolicy.class ) @@ -34,7 +35,8 @@ public ContinuousThresholdPolicy() } @Override - public CheckPointThreshold createThreshold( Config config, Clock clock, LogProvider logProvider ) + public CheckPointThreshold createThreshold( + Config config, Clock clock, LogPruning logPruning, LogProvider logProvider ) { return new ContinuousCheckPointThreshold(); } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/CountCommittedTransactionThreshold.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/CountCommittedTransactionThreshold.java index 11c97b2052872..91bd3656a9d96 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/CountCommittedTransactionThreshold.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/CountCommittedTransactionThreshold.java @@ -25,7 +25,7 @@ class CountCommittedTransactionThreshold extends AbstractCheckPointThreshold private volatile long nextTransactionIdTarget; - public CountCommittedTransactionThreshold( int notificationThreshold ) + CountCommittedTransactionThreshold( int notificationThreshold ) { super( "tx count threshold" ); this.notificationThreshold = notificationThreshold; diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/PeriodicThresholdPolicy.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/PeriodicThresholdPolicy.java index 686c39f637d14..4720e2a403662 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/PeriodicThresholdPolicy.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/PeriodicThresholdPolicy.java @@ -24,6 +24,7 @@ import org.neo4j.graphdb.factory.GraphDatabaseSettings; import org.neo4j.helpers.Service; import org.neo4j.kernel.configuration.Config; +import org.neo4j.kernel.impl.transaction.log.pruning.LogPruning; import org.neo4j.logging.LogProvider; import static org.neo4j.kernel.impl.transaction.log.checkpoint.CheckPointThreshold.or; @@ -41,7 +42,8 @@ public PeriodicThresholdPolicy() } @Override - public CheckPointThreshold createThreshold( Config config, Clock clock, LogProvider logProvider ) + public CheckPointThreshold createThreshold( + Config config, Clock clock, LogPruning logPruning, LogProvider logProvider ) { int txThreshold = config.get( GraphDatabaseSettings.check_point_interval_tx ); final CountCommittedTransactionThreshold countCommittedTransactionThreshold = diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/TimeCheckPointThreshold.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/TimeCheckPointThreshold.java index ed4827e4f5305..9a8d229f8b11a 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/TimeCheckPointThreshold.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/checkpoint/TimeCheckPointThreshold.java @@ -31,7 +31,7 @@ class TimeCheckPointThreshold extends AbstractCheckPointThreshold private final long timeMillisThreshold; private final Clock clock; - public TimeCheckPointThreshold( long thresholdMillis, Clock clock ) + TimeCheckPointThreshold( long thresholdMillis, Clock clock ) { super( "time threshold" ); this.timeMillisThreshold = thresholdMillis; diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/pruning/LogPruning.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/pruning/LogPruning.java index 94e06ebb1591a..cd92c844a0ff9 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/pruning/LogPruning.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/pruning/LogPruning.java @@ -37,4 +37,18 @@ public interface LogPruning * Otherwise {@code false} if we are pretty sure that we don't need to prune any logs right now. */ boolean mightHaveLogsToPrune(); + + LogPruning NO_PRUNING = new LogPruning() + { + @Override + public void pruneLogs( long currentVersion ) + { + } + + @Override + public boolean mightHaveLogsToPrune() + { + return false; + } + }; } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/checkpoint/CheckPointThresholdTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/checkpoint/CheckPointThresholdTest.java index 0343bf2243365..c5478a0f5b333 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/checkpoint/CheckPointThresholdTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/checkpoint/CheckPointThresholdTest.java @@ -19,84 +19,16 @@ */ package org.neo4j.kernel.impl.transaction.log.checkpoint; -import org.junit.Before; import org.junit.Test; -import java.time.Duration; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.function.Consumer; - -import org.neo4j.graphdb.factory.GraphDatabaseSettings; -import org.neo4j.kernel.configuration.Config; -import org.neo4j.logging.LogProvider; -import org.neo4j.logging.NullLogProvider; -import org.neo4j.time.Clocks; -import org.neo4j.time.FakeClock; - import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.neo4j.helpers.collection.MapUtil.stringMap; -public class CheckPointThresholdTest +public class CheckPointThresholdTest extends CheckPointThresholdTestSupport { - private Config config; - private FakeClock clock; - private LogProvider logProvider; - private Integer intervalTx; - private Duration intervalTime; - private Consumer notTriggered; - private BlockingQueue triggerConsumer; - private Consumer triggered; - - @Before - public void setUp() - { - config = Config.empty(); - clock = Clocks.fakeClock(); - logProvider = NullLogProvider.getInstance(); - intervalTx = config.get( GraphDatabaseSettings.check_point_interval_tx ); - intervalTime = config.get( GraphDatabaseSettings.check_point_interval_time ); - triggerConsumer = new LinkedBlockingQueue<>(); - triggered = triggerConsumer::offer; - notTriggered = s -> fail( "Should not have triggered: " + s ); - } - - private void withPolicy( String policy ) - { - config.augment( stringMap( GraphDatabaseSettings.check_point_policy.name(), policy ) ); - } - - private void withIntervalTime( String time ) - { - config.augment( stringMap( GraphDatabaseSettings.check_point_interval_time.name(), time ) ); - } - - private void withIntervalTx( int count ) - { - config.augment( stringMap( GraphDatabaseSettings.check_point_interval_tx.name(), String.valueOf( count ) ) ); - } - - private CheckPointThreshold createThreshold() - { - return CheckPointThreshold.createThreshold( config, clock, logProvider ); - } - - private void verifyTriggered( String reason ) - { - assertThat( triggerConsumer.poll(), containsString( reason ) ); - } - - private void verifyNoMoreTriggers() - { - assertTrue( triggerConsumer.isEmpty() ); - } - @Test public void mustCreateThresholdThatTriggersAfterTransactionCount() throws Exception { diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/checkpoint/CheckPointThresholdTestSupport.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/checkpoint/CheckPointThresholdTestSupport.java new file mode 100644 index 0000000000000..f1d36caf9271d --- /dev/null +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/checkpoint/CheckPointThresholdTestSupport.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2002-2017 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.kernel.impl.transaction.log.checkpoint; + +import org.junit.Before; + +import java.time.Duration; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.function.Consumer; + +import org.neo4j.graphdb.factory.GraphDatabaseSettings; +import org.neo4j.kernel.configuration.Config; +import org.neo4j.kernel.impl.transaction.log.pruning.LogPruning; +import org.neo4j.logging.LogProvider; +import org.neo4j.logging.NullLogProvider; +import org.neo4j.time.Clocks; +import org.neo4j.time.FakeClock; + +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.neo4j.helpers.collection.MapUtil.stringMap; + +public class CheckPointThresholdTestSupport +{ + protected Config config; + protected FakeClock clock; + protected LogPruning logPruning; + protected LogProvider logProvider; + protected Integer intervalTx; + protected Duration intervalTime; + protected Consumer notTriggered; + protected BlockingQueue triggerConsumer; + protected Consumer triggered; + + @Before + public void setUp() + { + config = Config.empty(); + clock = Clocks.fakeClock(); + logPruning = LogPruning.NO_PRUNING; + logProvider = NullLogProvider.getInstance(); + intervalTx = config.get( GraphDatabaseSettings.check_point_interval_tx ); + intervalTime = config.get( GraphDatabaseSettings.check_point_interval_time ); + triggerConsumer = new LinkedBlockingQueue<>(); + triggered = triggerConsumer::offer; + notTriggered = s -> fail( "Should not have triggered: " + s ); + } + + protected void withPolicy( String policy ) + { + config.augment( stringMap( GraphDatabaseSettings.check_point_policy.name(), policy ) ); + } + + protected void withIntervalTime( String time ) + { + config.augment( stringMap( GraphDatabaseSettings.check_point_interval_time.name(), time ) ); + } + + protected void withIntervalTx( int count ) + { + config.augment( stringMap( GraphDatabaseSettings.check_point_interval_tx.name(), String.valueOf( count ) ) ); + } + + protected CheckPointThreshold createThreshold() + { + return CheckPointThreshold.createThreshold( config, clock, logPruning, logProvider ); + } + + protected void verifyTriggered( String reason ) + { + assertThat( triggerConsumer.poll(), containsString( reason ) ); + } + + protected void verifyNoMoreTriggers() + { + assertTrue( triggerConsumer.isEmpty() ); + } +} diff --git a/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/transaction/log/checkpoint/VolumetricCheckPointPolicy.java b/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/transaction/log/checkpoint/VolumetricCheckPointPolicy.java new file mode 100644 index 0000000000000..e50339b53b33d --- /dev/null +++ b/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/transaction/log/checkpoint/VolumetricCheckPointPolicy.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2002-2017 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.neo4j.kernel.impl.enterprise.transaction.log.checkpoint; + +import java.time.Clock; + +import org.neo4j.helpers.Service; +import org.neo4j.kernel.configuration.Config; +import org.neo4j.kernel.impl.transaction.log.checkpoint.CheckPointThreshold; +import org.neo4j.kernel.impl.transaction.log.checkpoint.CheckPointThresholdPolicy; +import org.neo4j.kernel.impl.transaction.log.pruning.LogPruning; +import org.neo4j.logging.LogProvider; + +@Service.Implementation( CheckPointThresholdPolicy.class ) +public class VolumetricCheckPointPolicy extends CheckPointThresholdPolicy +{ + public VolumetricCheckPointPolicy() + { + super( "volumetric" ); + } + + @Override + public CheckPointThreshold createThreshold( + Config config, Clock clock, LogPruning logPruning, LogProvider logProvider ) + { + return new VolumetricCheckPointThreshold( logPruning ); + } +} diff --git a/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/transaction/log/checkpoint/VolumetricCheckPointThreshold.java b/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/transaction/log/checkpoint/VolumetricCheckPointThreshold.java new file mode 100644 index 0000000000000..01ba0d89d3a9d --- /dev/null +++ b/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/transaction/log/checkpoint/VolumetricCheckPointThreshold.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2002-2017 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.neo4j.kernel.impl.enterprise.transaction.log.checkpoint; + +import org.neo4j.kernel.impl.transaction.log.checkpoint.AbstractCheckPointThreshold; +import org.neo4j.kernel.impl.transaction.log.pruning.LogPruning; + +public class VolumetricCheckPointThreshold extends AbstractCheckPointThreshold +{ + private final LogPruning logPruning; + + public VolumetricCheckPointThreshold( LogPruning logPruning ) + { + super( "tx log pruning" ); + this.logPruning = logPruning; + } + + @Override + protected boolean thresholdReached( long lastCommittedTransactionId ) + { + return logPruning.mightHaveLogsToPrune(); + } + + @Override + public void initialize( long transactionId ) + { + } + + @Override + public void checkPointHappened( long transactionId ) + { + } +} diff --git a/enterprise/kernel/src/main/resources/META-INF/services/org.neo4j.kernel.impl.transaction.log.checkpoint.CheckPointThresholdPolicy b/enterprise/kernel/src/main/resources/META-INF/services/org.neo4j.kernel.impl.transaction.log.checkpoint.CheckPointThresholdPolicy new file mode 100644 index 0000000000000..03088aaa9eb2f --- /dev/null +++ b/enterprise/kernel/src/main/resources/META-INF/services/org.neo4j.kernel.impl.transaction.log.checkpoint.CheckPointThresholdPolicy @@ -0,0 +1 @@ +org.neo4j.kernel.impl.enterprise.transaction.log.checkpoint.VolumetricCheckPointPolicy diff --git a/enterprise/kernel/src/test/java/org/neo4j/kernel/impl/enterprise/transaction/log/checkpoint/VolumetricCheckPointThresholdTest.java b/enterprise/kernel/src/test/java/org/neo4j/kernel/impl/enterprise/transaction/log/checkpoint/VolumetricCheckPointThresholdTest.java new file mode 100644 index 0000000000000..907c82cf56b0c --- /dev/null +++ b/enterprise/kernel/src/test/java/org/neo4j/kernel/impl/enterprise/transaction/log/checkpoint/VolumetricCheckPointThresholdTest.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2002-2017 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.neo4j.kernel.impl.enterprise.transaction.log.checkpoint; + +import org.junit.Before; +import org.junit.Test; + +import org.neo4j.kernel.impl.transaction.log.checkpoint.CheckPointThreshold; +import org.neo4j.kernel.impl.transaction.log.checkpoint.CheckPointThresholdTestSupport; +import org.neo4j.kernel.impl.transaction.log.pruning.LogPruning; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +public class VolumetricCheckPointThresholdTest extends CheckPointThresholdTestSupport +{ + private boolean haveLogsToPrune; + + @Before + @Override + public void setUp() + { + super.setUp(); + logPruning = new LogPruning() + { + @Override + public void pruneLogs( long currentVersion ) + { + fail( "Check point threshold must never call out to prune logs directly." ); + } + + @Override + public boolean mightHaveLogsToPrune() + { + return haveLogsToPrune; + } + }; + } + + @Test + public void checkPointIsNeededIfWeMightHaveLogsToPrune() throws Exception + { + withPolicy( "volumetric" ); + haveLogsToPrune = true; + CheckPointThreshold threshold = createThreshold(); + threshold.initialize( 2 ); + assertTrue( threshold.isCheckPointingNeeded( 2, triggered ) ); + verifyTriggered( "log pruning" ); + verifyNoMoreTriggers(); + } + + @Test + public void checkPointIsInitiallyNotNeededIfWeHaveNoLogsToPrune() throws Exception + { + withPolicy( "volumetric" ); + haveLogsToPrune = false; + CheckPointThreshold threshold = createThreshold(); + threshold.initialize( 2 ); + assertFalse( threshold.isCheckPointingNeeded( 2, notTriggered ) ); + verifyNoMoreTriggers(); + } +}