All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sleepycat.je.util.DbSpace Maven / Gradle / Ivy

The newest version!
/*-
 * Copyright (C) 2002, 2018, 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.
 */

package com.sleepycat.je.util;

import java.io.File;
import java.io.PrintStream;
import java.text.DateFormat;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.Map;
import java.util.NavigableSet;
import java.util.SortedMap;

import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.DbInternal;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.JEVersion;
import com.sleepycat.je.cleaner.ExpirationProfile;
import com.sleepycat.je.cleaner.ExpirationTracker;
import com.sleepycat.je.cleaner.FileProcessor;
import com.sleepycat.je.cleaner.FileSummary;
import com.sleepycat.je.dbi.EnvironmentImpl;
import com.sleepycat.je.log.UtilizationFileReader;
import com.sleepycat.je.utilint.CmdUtil;
import com.sleepycat.je.utilint.DbLsn;
import com.sleepycat.utilint.FormatUtil;
import com.sleepycat.je.utilint.Pair;

/**
 * DbSpace displays the disk space utilization for an environment.
 * 
 * usage: java { com.sleepycat.je.util.DbSpace |
 *               -jar je-<version>.jar DbSpace }
 *          -h <dir># environment home directory
 *         [-q]     # quiet, print grand totals only
 *         [-u]     # sort by average utilization
 *         [-d]     # dump file summary details
 *         [-r]     # recalculate utilization (expensive)
 *         [-R]     # recalculate expired data (expensive)
 *         [-s]     # start file number or LSN, in hex
 *         [-e]     # end file number or LSN, in hex
 *         [-t]     # time for calculating expired data
 *                  #   format: yyyy-MM-dd'T'HHZ
 *                  #  example: 2016-03-09T22-0800
 *         [-V]     # print JE version number
 * 
*/ public class DbSpace { private static final String DATE_FORMAT = "yyyy-MM-dd'T'HHZ"; private static final String DATE_EXAMPLE = "2016-03-17T22-0800"; private static final String USAGE = "usage: " + CmdUtil.getJavaCommand(DbSpace.class) + "\n" + " -h
# environment home directory\n" + " [-q] # quiet, print grand totals only\n" + " [-u] # sort by average utilization\n" + " [-d] # dump file summary details\n" + " [-r] # recalculate utilization (expensive)\n" + " [-R] # recalculate expired data (expensive)\n" + " [-s] # start file number or LSN, in hex\n" + " [-e] # end file number or LSN, in hex\n" + " [-t] # time for calculating expired data,\n" + " # format: " + DATE_FORMAT + "\n" + " # example: " + DATE_EXAMPLE + "\n" + " [-V] # print JE version number"; public static void main(String argv[]) throws Exception { DbSpace space = new DbSpace(); space.parseArgs(argv); EnvironmentConfig envConfig = new EnvironmentConfig(); envConfig.setReadOnly(true); Environment env = new Environment(space.envHome, envConfig); space.initEnv(DbInternal.getNonNullEnvImpl(env)); try { space.print(System.out); System.exit(0); } catch (Throwable e) { e.printStackTrace(System.err); System.exit(1); } finally { try { env.close(); } catch (Throwable e) { e.printStackTrace(System.err); System.exit(1); } } } private File envHome = null; private EnvironmentImpl envImpl; private boolean quiet = false; private boolean sorted = false; private boolean details = false; private boolean doRecalcUtil = false; private boolean doRecalcExpired = false; private long startLsn = DbLsn.NULL_LSN; private long finishLsn = DbLsn.NULL_LSN; private long targetTime = System.currentTimeMillis(); private DbSpace() { } /** * Creates a DbSpace object for calculating utilization using an open * Environment. */ public DbSpace(Environment env, boolean quiet, boolean details, boolean sorted) { this(DbInternal.getNonNullEnvImpl(env), quiet, details, sorted); } /** * For internal use only. * @hidden */ public DbSpace(EnvironmentImpl envImpl, boolean quiet, boolean details, boolean sorted) { initEnv(envImpl); this.quiet = quiet; this.details = details; this.sorted = sorted; } private void initEnv(EnvironmentImpl envImpl) { this.envImpl = envImpl; } private void printUsage(String msg) { if (msg != null) { System.err.println(msg); } System.err.println(USAGE); System.exit(-1); } private void parseArgs(String argv[]) { int argc = 0; int nArgs = argv.length; if (nArgs == 0) { printUsage(null); System.exit(0); } while (argc < nArgs) { String thisArg = argv[argc++]; if (thisArg.equals("-q")) { quiet = true; } else if (thisArg.equals("-u")) { sorted = true; } else if (thisArg.equals("-d")) { details = true; } else if (thisArg.equals("-r")) { doRecalcUtil = true; } else if (thisArg.equals("-R")) { doRecalcExpired = true; } else if (thisArg.equals("-V")) { System.out.println(JEVersion.CURRENT_VERSION); System.exit(0); } else if (thisArg.equals("-h")) { if (argc < nArgs) { envHome = new File(argv[argc++]); } else { printUsage("-h requires an argument"); } } else if (thisArg.equals("-s")) { if (argc < nArgs) { startLsn = CmdUtil.readLsn(argv[argc++]); } else { printUsage("-s requires an argument"); } } else if (thisArg.equals("-e")) { if (argc < nArgs) { finishLsn = CmdUtil.readLsn(argv[argc++]); } else { printUsage("-e requires an argument"); } } else if (thisArg.equals("-t")) { if (argc < nArgs) { String s = argv[argc++]; DateFormat format = new SimpleDateFormat(DATE_FORMAT); ParsePosition pp = new ParsePosition(0); Date date = format.parse(s, pp); if (date != null) { targetTime = date.getTime(); } else { printUsage( "-t doesn't match format: " + DATE_FORMAT + " example: " + DATE_EXAMPLE); } } else { printUsage("-t requires an argument"); } } } if (envHome == null) { printUsage("-h is a required argument"); } if (doRecalcUtil && doRecalcExpired) { printUsage("-r and -R cannot both be used"); } } /** * Sets the recalculation property, which if true causes a more expensive * recalculation of utilization to be performed for debugging purposes. * This property is false by default. */ public void setRecalculate(boolean recalc) { this.doRecalcUtil = recalc; } /** * Sets the start file number, which is a lower bound on the range of * files for which utilization is reported and (optionally) recalculated. * By default there is no lower bound. */ public void setStartFile(long startFile) { this.startLsn = startFile; } /** * Sets the ending file number, which is an upper bound on the range of * files for which utilization is reported and (optionally) recalculated. * By default there is no upper bound. */ public void setEndFile(long endFile) { this.finishLsn = endFile; } /** * Sets the time for calculating expired data. */ public void setTime(long time) { targetTime = time; } /** * Calculates utilization and prints a report to the given output stream. */ public void print(PrintStream out) throws DatabaseException { long startFile = (startLsn != DbLsn.NULL_LSN) ? DbLsn.getFileNumber(startLsn) : 0; long finishFile = (finishLsn != DbLsn.NULL_LSN) ? DbLsn.getFileNumber(finishLsn) : Long.MAX_VALUE; SortedMap map = envImpl.getUtilizationProfile().getFileSummaryMap(true). subMap(startFile, finishFile); map.keySet().removeAll( envImpl.getCleaner().getFileSelector().getInProgressFiles()); Map recalcMap = doRecalcUtil ? UtilizationFileReader.calcFileSummaryMap( envImpl, startLsn, finishLsn) : null; ExpirationProfile expProfile = new ExpirationProfile(envImpl.getExpirationProfile()); expProfile.refresh(targetTime); int fileIndex = 0; Summary totals = new Summary(); Summary[] summaries = null; if (!quiet) { summaries = new Summary[map.size()]; } for (Map.Entry entry : map.entrySet()) { Long fileNum = entry.getKey(); FileSummary fs = entry.getValue(); FileSummary recalcFs = null; if (recalcMap != null) { recalcFs = recalcMap.get(fileNum); } int expiredSize = expProfile.getExpiredBytes(fileNum); int recalcExpiredSize = -1; ExpirationTracker expTracker = null; if (doRecalcExpired) { FileProcessor fileProcessor = envImpl.getCleaner().createProcessor(); expTracker = fileProcessor.countExpiration(fileNum); recalcExpiredSize = expTracker.getExpiredBytes(targetTime); } Summary summary = new Summary( fileNum, fs, recalcFs, expiredSize, recalcExpiredSize); if (summaries != null) { summaries[fileIndex] = summary; } if (details) { out.println( "File 0x" + Long.toHexString(fileNum) + " expired: " + expiredSize + " histogram: " + expProfile.toString(fileNum) + " " + fs); if (recalcMap != null) { out.println( "Recalc util 0x" + Long.toHexString(fileNum) + " " + recalcFs); } if (expTracker != null) { out.println( "Recalc expiration 0x" + Long.toHexString(fileNum) + " recalcExpired: " + recalcExpiredSize + " recalcHistogram: " + expTracker.toString()); } } totals.add(summary); fileIndex += 1; } if (details) { out.println(); } out.println( doRecalcExpired ? Summary.RECALC_EXPIRED_HEADER : (doRecalcUtil ? Summary.RECALC_HEADER : Summary.HEADER)); if (summaries != null) { if (sorted) { Arrays.sort(summaries, new Comparator() { public int compare(Summary s1, Summary s2) { return s1.avgUtilization() - s2.avgUtilization(); } }); } for (Summary summary : summaries) { summary.print(out); } } totals.print(out); if (totals.expiredSize > 0) { DateFormat format = new SimpleDateFormat(DATE_FORMAT); out.format( "%nAs of %s, %,d kB are expired, resulting in the%n" + "differences between minimum and maximum utilization.%n", format.format(targetTime), totals.expiredSize / 1024); } Pair> reservedFileInfo = envImpl.getFileProtector().getReservedFileInfo(); long reservedSize = reservedFileInfo.first(); NavigableSet reservedFiles = reservedFileInfo.second(); boolean printReservedFiles = !quiet && !reservedFiles.isEmpty(); out.format( "%n%,d kB are used by additional reserved files%s%n", reservedSize / 1024, printReservedFiles ? ":" : "."); if (printReservedFiles) { out.println(FormatUtil.asHexString(reservedFiles)); } } private class Summary { static final String HEADER = " % Utilized\n" + " File Size (kB) Avg Min Max \n" + "-------- --------- ---- --- ---"; // 12345678 123456789 123 123 123 // 12 12 12 12 // TOTALS: static final String RECALC_HEADER = " % Utilized Recalculated\n" + " File Size (kB) Avg Min Max Avg Min Max\n" + "-------- --------- --- --- --- --- --- ---"; // 12345678 123456789 123 123 123 123 123 123 // 12 12 12 12 12 12 12 // TOTALS: static final String RECALC_EXPIRED_HEADER = " % Utilized w/Expiration\n" + " File Size (kB) Avg Min Max Recalculated\n" + "-------- --------- --- --- --- ------------"; // 12345678 123456789 123 123 123 123 // 12 12 12 12 123456 // TOTALS: Long fileNum; long totalSize; long obsoleteSize; long recalcObsoleteSize; long expiredSize; long recalcExpiredSize; Summary() {} Summary(Long fileNum, FileSummary summary, FileSummary recalcSummary, int expiredSize, int recalcExpiredSize) { this.fileNum = fileNum; totalSize = summary.totalSize; obsoleteSize = summary.getObsoleteSize(); if (recalcSummary != null) { recalcObsoleteSize = recalcSummary.getObsoleteSize(); } this.expiredSize = Math.min(expiredSize, totalSize); this.recalcExpiredSize = Math.min(recalcExpiredSize, totalSize); } void add(Summary o) { totalSize += o.totalSize; obsoleteSize += o.obsoleteSize; recalcObsoleteSize += o.recalcObsoleteSize; expiredSize += o.expiredSize; recalcExpiredSize += o.recalcExpiredSize; } void print(PrintStream out) { if (fileNum != null) { pad(out, Long.toHexString(fileNum.longValue()), 8, '0'); } else { out.print(" TOTALS "); } int kb = (int) (totalSize / 1024); out.print(" "); pad(out, Integer.toString(kb), 9, ' '); out.print(" "); pad(out, Integer.toString(avgUtilization()), 3, ' '); out.print(" "); pad(out, Integer.toString(minUtilization()), 3, ' '); out.print(" "); pad(out, Integer.toString(maxUtilization()), 3, ' '); if (doRecalcExpired) { out.print(" "); pad(out, Integer.toString(expRecalcUtilization()), 3, ' '); } else if (doRecalcUtil) { out.print(" "); pad(out, Integer.toString(avgRecalcUtilization()), 3, ' '); out.print(" "); pad(out, Integer.toString(minRecalcUtilization()), 3, ' '); out.print(" "); pad(out, Integer.toString(maxRecalcUtilization()), 3, ' '); } out.println(); } int avgUtilization() { return (minUtilization() + maxUtilization()) / 2; } int minUtilization() { return minUtilization(obsoleteSize, expiredSize); } int maxUtilization() { return maxUtilization(obsoleteSize, expiredSize); } int expRecalcUtilization() { return minUtilization(obsoleteSize, recalcExpiredSize); } int avgRecalcUtilization() { return (minRecalcUtilization() + maxRecalcUtilization()) / 2; } int minRecalcUtilization() { return minUtilization(recalcObsoleteSize, expiredSize); } int maxRecalcUtilization() { return maxUtilization(recalcObsoleteSize, expiredSize); } private int minUtilization(long obsolete, long expired) { return FileSummary.utilization( Math.min(obsolete + expired, totalSize), totalSize); } private int maxUtilization(long obsolete, long expired) { return FileSummary.utilization( Math.max(obsolete, expired), totalSize); } private void pad(PrintStream out, String val, int digits, char padChar) { int padSize = digits - val.length(); for (int i = 0; i < padSize; i += 1) { out.print(padChar); } out.print(val); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy