-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
CheckPointingLogRotationStressTesting.java
124 lines (110 loc) · 5.86 KB
/
CheckPointingLogRotationStressTesting.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*
* Copyright (c) 2002-2016 "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 <http://www.gnu.org/licenses/>.
*/
package org.neo4j.kernel.stresstests.transaction.checkpoint;
import org.junit.Test;
import java.io.File;
import java.util.concurrent.TimeUnit;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
import org.neo4j.graphdb.factory.GraphDatabaseSettings;
import org.neo4j.io.fs.DefaultFileSystemAbstraction;
import org.neo4j.io.fs.FileSystemAbstraction;
import org.neo4j.io.fs.FileUtils;
import org.neo4j.kernel.configuration.Config;
import org.neo4j.kernel.configuration.Settings;
import org.neo4j.kernel.impl.factory.GraphDatabaseFacadeFactory;
import org.neo4j.kernel.impl.logging.NullLogService;
import org.neo4j.kernel.stresstests.transaction.checkpoint.tracers.TimerTransactionTracer;
import org.neo4j.kernel.stresstests.transaction.checkpoint.workload.Workload;
import org.neo4j.unsafe.impl.batchimport.ParallelBatchImporter;
import org.neo4j.unsafe.impl.batchimport.staging.ExecutionMonitors;
import static java.lang.Integer.parseInt;
import static java.lang.Long.parseLong;
import static java.lang.System.getProperty;
import static org.neo4j.StressTestingHelper.ensureExistsAndEmpty;
import static org.neo4j.StressTestingHelper.fromEnv;
import static org.neo4j.kernel.stresstests.transaction.checkpoint.mutation.RandomMutationFactory.defaultRandomMutation;
import static org.neo4j.unsafe.impl.batchimport.Configuration.DEFAULT;
/**
* Notice the class name: this is _not_ going to be run as part of the main build.
*/
public class CheckPointingLogRotationStressTesting
{
private static final String DEFAULT_DURATION_IN_MINUTES = "5";
private static final String DEFAULT_STORE_DIR = new File( getProperty( "java.io.tmpdir" ), "store" ).getPath();
private static final String DEFAULT_NODE_COUNT = "100000";
private static final String DEFAULT_WORKER_THREADS = "16";
private static final String DEFAULT_PAGE_CACHE_MEMORY = "4g";
private static final String DEFAULT_PAGE_SIZE = "8k";
private static final int CHECK_POINT_INTERVAL_MINUTES = 1;
@Test
public void shouldBehaveCorrectlyUnderStress() throws Throwable
{
long durationInMinutes =
parseLong( fromEnv( "CHECK_POINT_LOG_ROTATION_STRESS_DURATION", DEFAULT_DURATION_IN_MINUTES ) );
File storeDir = new File( fromEnv( "CHECK_POINT_LOG_ROTATION_STORE_DIRECTORY", DEFAULT_STORE_DIR ) );
long nodeCount = parseLong( fromEnv( "CHECK_POINT_LOG_ROTATION_NODE_COUNT", DEFAULT_NODE_COUNT ) );
int threads = parseInt( fromEnv( "CHECK_POINT_LOG_ROTATION_WORKER_THREADS", DEFAULT_WORKER_THREADS ) );
String pageCacheMemory = fromEnv( "CHECK_POINT_LOG_ROTATION_PAGE_CACHE_MEMORY", DEFAULT_PAGE_CACHE_MEMORY );
String pageSize = fromEnv( "CHECK_POINT_LOG_ROTATION_PAGE_SIZE", DEFAULT_PAGE_SIZE );
System.out.println( "1/6\tBuilding initial store..." );
try ( FileSystemAbstraction fileSystem = new DefaultFileSystemAbstraction())
{
new ParallelBatchImporter( ensureExistsAndEmpty( storeDir ), fileSystem, DEFAULT,
NullLogService.getInstance(), ExecutionMonitors.defaultVisible(), Config.defaults() )
.doImport( new NodeCountInputs( nodeCount ) );
}
System.out.println( "2/6\tStarting database..." );
GraphDatabaseService db = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder( storeDir )
.setConfig( GraphDatabaseSettings.pagecache_memory, pageCacheMemory )
.setConfig( GraphDatabaseSettings.mapped_memory_page_size, pageSize )
.setConfig( GraphDatabaseSettings.keep_logical_logs, Settings.FALSE )
.setConfig( GraphDatabaseSettings.check_point_interval_time, CHECK_POINT_INTERVAL_MINUTES + "m" )
.setConfig( GraphDatabaseFacadeFactory.Configuration.tracer, "timer" )
.newGraphDatabase();
System.out.println("3/6\tWarm up db...");
try ( Workload workload = new Workload( db, defaultRandomMutation( nodeCount, db ), threads ) )
{
// make sure to run at least one checkpoint during warmup
long warmUpTimeMillis = TimeUnit.SECONDS.toMillis( CHECK_POINT_INTERVAL_MINUTES * 2 );
workload.run( warmUpTimeMillis, Workload.TransactionThroughput.NONE );
}
System.out.println( "4/6\tStarting workload..." );
TransactionThroughputChecker throughput = new TransactionThroughputChecker();
try ( Workload workload = new Workload( db, defaultRandomMutation( nodeCount, db ), threads ) )
{
workload.run( TimeUnit.MINUTES.toMillis( durationInMinutes ), throughput );
}
System.out.println( "5/6\tShutting down..." );
db.shutdown();
try
{
System.out.println( "6/6\tPrinting stats and recorded timings..." );
TimerTransactionTracer.printStats( System.out );
throughput.assertThroughput( System.out );
}
finally
{
System.out.println( "Done." );
}
// let's cleanup disk space when everything went well
FileUtils.deleteRecursively( storeDir );
}
}