/* This file is part of VoltDB. * Copyright (C) 2008-2017 VoltDB Inc. * * This program 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 VoltDB. If not, see <http://www.gnu.org/licenses/>. */ package org.voltdb.utils; import java.io.File; import java.io.FileFilter; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.voltcore.logging.VoltLogger; import org.voltdb.sysprocs.saverestore.SnapshotUtil; import org.voltdb.sysprocs.saverestore.SnapshotUtil.Snapshot; import org.voltdb.sysprocs.saverestore.SnapshotUtil.SnapshotFilter; import org.voltdb.sysprocs.saverestore.SnapshotPathType; import org.voltdb.sysprocs.saverestore.SnapshotUtil.SpecificSnapshotFilter; /** * A command line utility for scanning and validating snapshots. Provides detailed information about the files * that make up a snapshot, what partitions they contains, and whether they are corrupted or intact. In the event * that a table file is corrupted it will also specify what partitions can still be salvaged. * */ public class SnapshotVerifier { private static final VoltLogger CONSOLE_LOG = new VoltLogger("CONSOLE"); public static void main(String args[]) { if (args.length == 0) { //printHelpAndQuit(0); } else if (args[0].equals("--help")) { printHelpAndQuit(0); } HashSet<String> snapshotNames = new HashSet<String>(); for (int ii = 0; ii < args.length; ii++) { if (args[ii].equals("--dir")) { ii++; continue; } snapshotNames.add(args[ii]); } List<String> directories = new ArrayList<String>(); for (int ii = 0; ii < args.length; ii++) { if (args[ii].equals("--dir")) { if (ii + 1 >= args.length) { System.err.println("Error: No directories specified after --dir"); printHelpAndQuit(-1); break; } directories.add(args[ii + 1]); ii++; } } if (directories.isEmpty()) { directories.add("."); } verifySnapshots(directories, snapshotNames, false); } /** * Perform snapshot verification. * @param directories list of directories to search for snapshots * @param snapshotNames set of snapshot names/nonces to verify */ public static void verifySnapshots( final List<String> directories, final Set<String> snapshotNames, boolean expectHashinator) { FileFilter filter = new SnapshotFilter(); if (!snapshotNames.isEmpty()) { filter = new SpecificSnapshotFilter(snapshotNames); } Map<String, Snapshot> snapshots = new HashMap<String, Snapshot>(); for (String directory : directories) { SnapshotUtil.retrieveSnapshotFiles(new File(directory), snapshots, filter, true, SnapshotPathType.SNAP_PATH, CONSOLE_LOG); } if (snapshots.isEmpty()) { System.out.println("Snapshot corrupted"); System.out.println("No files found"); } for (Snapshot s : snapshots.values()) { System.out.println(SnapshotUtil.generateSnapshotReport(s.getTxnId(), s, expectHashinator).getSecond()); } } private static void printHelpAndQuit( int code) { System.out.println("Usage: snapshotverifier --help"); System.out.println("Specific snapshot: snapshotverifier snapshot_name --dir dir1 --dir dir2 --dir dir3"); System.out.println("All snapshots: snapshotverifier --dir dir1 --dir dir2 --dir dir3"); System.exit(code); } }