je/test/standalone/Utils.java
2021-06-06 13:46:45 -04:00

265 lines
9.6 KiB
Java
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*-
* Copyright (C) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
*
* This file was distributed by Oracle as part of a version of Oracle Berkeley
* DB Java Edition made available at:
*
* http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html
*
* Please see the LICENSE file included in the top-level directory of the
* appropriate version of Oracle Berkeley DB Java Edition for a copy of the
* license and additional information.
*/
import java.io.File;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.DbInternal;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.StatsConfig;
import com.sleepycat.je.rep.RepInternal;
import com.sleepycat.je.rep.ReplicatedEnvironment;
import com.sleepycat.je.rep.ReplicationMutableConfig;
import com.sleepycat.je.rep.utilint.RepTestUtils;
import com.sleepycat.je.rep.utilint.RepTestUtils.RepEnvInfo;
import com.sleepycat.je.utilint.VLSN;
import com.sleepycat.persist.EntityStore;
import com.sleepycat.persist.StoreConfig;
/**
* Utility methods to support replication standalone tests.
*/
public class Utils {
public static final boolean VERBOSE = Boolean.getBoolean("verbose");
public static final String DB_NAME = "testDb";
/**
* Create an EnvironmentConfig for ReplicatedEnvironments.
*/
public static EnvironmentConfig createEnvConfig(long fileSize,
long maxDisk,
long checkpointBytes,
int subDir,
long mainCacheSize,
long offHeapCacheSize) {
EnvironmentConfig envConfig =
RepTestUtils.createEnvConfig(RepTestUtils.DEFAULT_DURABILITY);
envConfig.setConfigParam(EnvironmentConfig.ENV_RUN_CLEANER, "true");
/*
* Set smaller log file max size and checkpointer interval bytes, so
* that the log cleaning takes place in this test.
*/
DbInternal.disableParameterValidation(envConfig);
envConfig.setConfigParam(
EnvironmentConfig.LOG_FILE_MAX,
String.valueOf(fileSize));
envConfig.setConfigParam(
EnvironmentConfig.CHECKPOINTER_BYTES_INTERVAL,
String.valueOf(checkpointBytes));
if (maxDisk != 0) {
envConfig.setConfigParam(
EnvironmentConfig.MAX_DISK, String.valueOf(maxDisk));
/* Set a small FREE_DISK since it is subtracted from MAX_DISK. */
envConfig.setConfigParam(
EnvironmentConfig.FREE_DISK, String.valueOf(1 << 20));
}
if (subDir > 0) {
envConfig.setConfigParam
(EnvironmentConfig.LOG_N_DATA_DIRECTORIES, subDir + "");
}
envConfig.setCacheSize(mainCacheSize);
envConfig.setOffHeapCacheSize(offHeapCacheSize);
return envConfig;
}
/* Start up the group and return the generated RepEnvInfo array. */
static RepEnvInfo[] setupGroup(File envRoot,
int nNodes,
long fileSize,
long maxDisk,
long checkpointBytes,
int subDir,
long mainCacheSize,
long offHeapCacheSize)
throws Exception {
RepEnvInfo[] repEnvInfo = RepTestUtils.setupEnvInfos(
envRoot, nNodes,
createEnvConfig(
fileSize, maxDisk, checkpointBytes, subDir, mainCacheSize,
offHeapCacheSize));
if (subDir > 0) {
RepTestUtils.createRepSubDirs(repEnvInfo, subDir);
}
if (nNodes == 2) {
repEnvInfo[0].getRepConfig().setDesignatedPrimary(true);
}
return repEnvInfo;
}
/*
* Join the ReplicatedEnvironments of a group of RepEnvInfo and return the
* authoritative master (wait for election to quiesce).
*/
public static ReplicatedEnvironment getMaster(RepEnvInfo[] repEnvInfo) {
return RepTestUtils.getMaster(repEnvInfo, true /*openIfNeeded*/);
}
public static ReplicatedEnvironment assignMaster(RepEnvInfo[] repEnvInfo,
int masterId,
boolean restart)
throws Exception {
assert repEnvInfo.length == 2 :
"This method can only be called by a replication group size of 2.";
ReplicationMutableConfig newConfig = new ReplicationMutableConfig();
newConfig.setDesignatedPrimary(true);
if (restart) {
repEnvInfo[masterId - 1].getRepConfig().setDesignatedPrimary(false);
repEnvInfo[masterId - 1].openEnv();
} else {
repEnvInfo[2 - masterId].getEnv().setRepMutableConfig(newConfig);
}
assert repEnvInfo[2 - masterId].getEnv().getState().isMaster() :
"Can't find out a master.";
return repEnvInfo[2 - masterId].getEnv();
}
/* Create or open a database for test. */
public static EntityStore openStore(ReplicatedEnvironment repEnv,
String dbName)
throws DatabaseException {
StoreConfig config = new StoreConfig();
config.setAllowCreate(true);
config.setTransactional(true);
return new EntityStore(repEnv, dbName, config);
}
/**
* Sync replicas to the master, and check that all nodes have the same
* contents.
*/
public static void doSyncAndCheck(RepEnvInfo[] replicators)
throws Exception {
/* Do the sync and check the node equality. */
VLSN commitVLSN =
RepTestUtils.syncGroupToLastCommit(replicators,
replicators.length);
RepTestUtils.checkNodeEquality(commitVLSN, VERBOSE, replicators);
}
/* Check the log cleaning and close the replicas. */
public static void closeEnvAndCheckLogCleaning(RepEnvInfo[] repEnvInfo,
long[] fileDeletions,
boolean checkCleaning)
throws Exception {
/* Initiate an array for saving the largest log file number. */
long [] lastFileNumbers = new long[repEnvInfo.length];
if (checkCleaning) {
/* Get the cleaner deletion stat for all replicas. */
int index = 0;
/* A stats config for getting stats. */
StatsConfig stConfig = new StatsConfig();
stConfig.setFast(true);
stConfig.setClear(true);
for (RepEnvInfo repInfo : repEnvInfo) {
if (repInfo.getEnv() != null &&
repInfo.getEnv().isValid()) {
ReplicatedEnvironment repEnv = repInfo.getEnv();
fileDeletions[index] +=
repEnv.getStats(stConfig).getNCleanerDeletions();
/* Get largest log file number for each environment. */
lastFileNumbers[index] =
RepInternal.getNonNullRepImpl(repEnv).
getFileManager().getLastFileNum();
}
index++;
}
}
/* Shut down the replicas. */
RepTestUtils.shutdownRepEnvs(repEnvInfo);
if (checkCleaning) {
/* Check if there is replica doesn't do log cleaning. */
for (int i = 0; i < fileDeletions.length; i++) {
System.err.println("Deleted files on replica " + i + " = " +
fileDeletions[i]);
System.err.println("Total used log files on replica " + i +
" = " + (lastFileNumbers[i] + 1));
if ((fileDeletions[i] * 100) / (lastFileNumbers[i] + 1) < 40) {
throw new IllegalStateException
("Expect to see log cleaning on replica " + i +
" exceeds 40%, but it doesn't.");
}
}
}
}
public static void createSubDirs(File envHome, int subDirNumber) {
createSubDirs(envHome, subDirNumber, false);
}
public static void createSubDirs(File envHome,
int subDirNumber,
boolean useExistEnvHome) {
if (!envHome.exists()) {
throw new IllegalStateException
("The environment home is not created yet.");
}
for (int i = 1; i <= subDirNumber; i++) {
String fileName = null;
if (i < 10) {
fileName = "data00" + i;
} else if (i < 100) {
fileName = "data0" + i;
} else if (i <= 256) {
fileName = "data" + i;
} else {
throw new IllegalArgumentException
("The number of sub directories is invalid.");
}
File subDir = new File(envHome, fileName);
if (subDir.exists() && useExistEnvHome) {
continue;
}
if (subDir.exists()) {
throw new IllegalStateException
("The sub directories shouldn't be created yet.");
}
if (!subDir.mkdir()) {
throw new IllegalStateException
("The sub directories are not created successfully.");
}
}
}
}