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

com.sleepycat.je.util.DbBackup 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.util.NavigableSet;

import com.sleepycat.je.CheckpointConfig;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.DbInternal;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentFailureException;
import com.sleepycat.je.EnvironmentStats;
import com.sleepycat.je.cleaner.EraserAbortException;
import com.sleepycat.je.cleaner.FileProtector;
import com.sleepycat.je.cleaner.FileProtector.ProtectedActiveFileSet;
import com.sleepycat.je.cleaner.FileProtector.ProtectedFileRange;
import com.sleepycat.je.config.EnvironmentParams;
import com.sleepycat.je.dbi.EnvironmentImpl;
import com.sleepycat.je.log.FileManager;
import com.sleepycat.je.log.LogEntryType;
import com.sleepycat.je.log.ReplicationContext;
import com.sleepycat.je.log.entry.EmptyLogEntry;
import com.sleepycat.je.log.entry.LogEntry;
import com.sleepycat.je.log.entry.SingleItemEntry;
import com.sleepycat.je.utilint.DbLsn;
import com.sleepycat.je.utilint.TestHook;
import com.sleepycat.je.utilint.TestHookExecute;

/**
 * DbBackup is a helper class for stopping and restarting JE background
 * activity in an open environment in order to simplify backup operations. It
 * also lets the application create a backup which can support restoring the
 * environment to a specific point in time.
 * 

* Backing up without DbBackup *

* Because JE has an append only log file architecture, it is always possible * to do a hot backup without the use of DbBackup by copying all log files * (.jdb files) to your archival location. As long as the log files are copied * in alphabetical order, (numerical in effect) and all log files are * copied, the environment can be successfully backed up without any need to * stop database operations or background activity. This means that your * backup operation must do a loop to check for the creation of new log files * before deciding that the backup is finished. For example: *

 * time    files in                    activity
 *         environment
 *
 *  t0     000000001.jdb     Backup starts copying file 1
 *         000000003.jdb
 *         000000004.jdb
 *
 *  t1     000000001.jdb     JE log cleaner migrates portion of file 3 to newly
 *         000000004.jdb     created file 5 and deletes file 3. Backup finishes
 *         000000005.jdb     file 1, starts copying file 4. Backup MUST include
 *                           file 5 for a consistent backup!
 *
 *  t2     000000001.jdb     Backup finishes copying file 4, starts and
 *         000000004.jdb     finishes file 5, has caught up. Backup ends.
 *         000000005.jdb
 *
*

* In the example above, the backup operation must be sure to copy file 5, * which came into existence after the backup had started. If the backup * stopped operations at file 4, the backup set would include only file 1 and * 4, omitting file 3, which would be an inconsistent set. *

* Also note that log file 5 may not have filled up before it was copied to * archival storage. On the next backup, there might be a newer, larger version * of file 5, and that newer version should replace the older file 5 in archive * storage. *

* Using the approach above, as opposed to using DbBackup, will copy all files * including {@link EnvironmentStats#getReservedLogSize reserved files} as well * as {@link EnvironmentStats#getActiveLogSize active files}. A large number of * reserved files may be present in an HA Environment, and they are essentially * wasted space in a backup. Using DbBackup is strongly recommended for this * reason, as well as to reduce the complexity of file copying. *

* Backing up with DbBackup *

* DbBackup helps simplify application backup by defining the set of {@link * EnvironmentStats#getActiveLogSize active files} that must be copied for each * backup operation. If the environment directory has read/write protection, * the application must pass DbBackup an open, read/write environment handle. *

* When entering backup mode, JE determines the set of active files needed for * a consistent backup, and freezes all changes to those files. The application * can copy that defined set of files and finish operation without checking for * the ongoing creation of new files. Also, there will be no need to check for * a newer version of the last file on the next backup. *

* In the example above, if DbBackup was used at t0, the application would only * have to copy files 1, 3 and 4 to back up. On a subsequent backup, the * application could start its copying at file 5. There would be no need to * check for a newer version of file 4. *

* When it is important to minimize the time that it takes to recover using a * backup, a checkpoint should be performed immediately before calling {@link * #startBackup}. This will reduce recovery time when opening the environment * with the restored log files. A checkpoint is performed explicitly by * calling {@link Environment#checkpoint} using a config object for which * {@link CheckpointConfig#setForce setForce(true)} has been called. *

* Performing simple/full backups *

* The following examples shows how to perform a full backup. A checkpoint is * performed to minimize recovery time. *

 * void myBackup(Environment env, File destDir) {
 *     DbBackup backupHelper = new DbBackup(env);
 *
 *     // Optional: Do a checkpoint to reduce recovery time after a restore.
 *     env.checkpoint(new CheckpointConfig().setForce(true));
 *
 *     // Start backup, find out what needs to be copied.
 *     backupHelper.startBackup();
 *     try {
 *         // Copy the necessary files to archival storage.
 *         String[] filesToCopy = backupHelper.getLogFilesInBackupSet();
 *         myCopyFiles(env, backupHelper, filesToCopy, destDir);
 *     } finally {
 *         // Remember to exit backup mode, or the JE cleaner cannot delete
 *         // log files and disk usage will grow without bounds.
 *        backupHelper.endBackup();
 *     }
 * }
 *
 * void myCopyFiles(
 *     Environment env,
 *     DbBackup backupHelper,
 *     String[] filesToCopy,
 *     File destDir) {
 *
 *     for (String fileName : filesToCopy) {
 *         // Copy fileName to destDir.
 *         // See {@link LogVerificationReadableByteChannel} and
 *         // {@link LogVerificationInputStream}.
 *         ....
 *
 *         // Remove protection to allow file to be deleted in order to reclaim
 *         // disk space.
 *         backupHelper.removeFileProtection(fileName);
 *     }
 * }
 * 
* When copying files to the backup directory, it is critical that each file is * verified before or during the copy. If a file is copied that is corrupt * (due to an earlier disk failure that went unnoticed, for example), the * backup will be invalid and provide a false sense of security. *

* The {@link LogVerificationInputStream example here} shows how to implement * the {@code myCopyFiles} method using {@link * LogVerificationInputStream}. A {@link LogVerificationReadableByteChannel} * could also be used for higher performance copying. A filter input stream is * used to verify the file efficiently as it is being read. If you choose to * use a script for copying files, the {@link DbVerifyLog} command line tool * can be used instead. *

* Assuming that the full backup copied files into an empty directory, to * restore you can simply copy these files back into another empty directory. *

* Always start with an empty directory as the destination for a full backup or * a restore, to ensure that no unused files are present. Unused files -- * perhaps the residual of an earlier environment or an earlier backup -- will * take up space, and they will never be deleted by the JE log cleaner. Also * note that such files will not be used by JE for calculating utilization and * will not appear in the {@link DbSpace} output. *

* Performing incremental backups *

* Incremental backups are used to reduce the number of files copied during * each backup. Compared to a full backup, there are two additional pieces of * information needed for an incremental backup: the number of the last file in * the previous backup, and a list of the active files in the environment * directory at the time of the current backup, i.e., the current snapshot. * Their purpose is explained below. *

* The number of the last file in the previous backup is used to avoid copying * files that are already present in the backup set. This file number must be * obtained before beginning the backup, either by checking the backup archive, * or getting this value from a stored location. For example, the last file * number could be written to a special file in the backup set at the time of a * backup, and then read from the special file before starting the next backup. *

* The list of files in the current snapshot, which should be obtained by * calling {@link #getLogFilesInSnapshot} (after calling {@link #startBackup}), * is used to avoid unused files after a restore, and may also be used to * reduce the size of the backup set. How to use this list is described below. *

* Some applications need the ability to restore to the point in time of any of * the incremental backups that were made in the past, and other applications * only need to restore to the point in time of the most recent backup. * Accordingly, the list of current files (that is made at the time of the * backup), should be used in one of two ways. *

    *
  1. If you only need to restore to the point in time of the most recent * backup, then the list should be used to delete unused files from the * backup set. After copying all files during the backup, any file that is * not present in the list may then be deleted from the backup set. * This both reduces the size of the backup set, and ensures that unused * files will not be present in the backup set and therefore will not be * restored.
  2. *
  3. If you need to keep all log files from each backup so you can restore * to more than one point in time, then the list for each backup should be * saved with the backup file set so it can be used during a restore. During * the restore, only the files in the list should be copied, starting with an * empty destination directory. This ensures that unused files will not be * restored.
  4. *
*

* The following two examples shows how to perform an incremental backup. In * the first example, the list of current files is used to delete files from * the backup set that are no longer needed. *

 * void myBackup(Environment env, File destDir) {
 *
 *     // Get the file number of the last file in the previous backup.
 *     long lastFileInPrevBackup =  ...
 *
 *     DbBackup backupHelper = new DbBackup(env, lastFileInPrevBackup);
 *
 *     // Optional: Do a checkpoint to reduce recovery time after a restore.
 *     env.checkpoint(new CheckpointConfig().setForce(true));
 *
 *     // Start backup, find out what needs to be copied.
 *     backupHelper.startBackup();
 *     try {
 *         // Copy the necessary files to archival storage.
 *         String[] filesToCopy = backupHelper.getLogFilesInBackupSet();
 *         myCopyFiles(env, backupHelper, filesToCopy, destDir);
 *
 *         // Delete files that are no longer needed.
 *         // WARNING: This should only be done after copying all new files.
 *         String[] filesInSnapshot = backupHelper.getLogFilesInSnapshot();
 *         myDeleteUnusedFiles(destDir, filesInSnapshot);
 *
 *         // Update knowledge of last file saved in the backup set.
 *         lastFileInPrevBackup = backupHelper.getLastFileInBackupSet();
 *         // Save lastFileInPrevBackup persistently here ...
 *     } finally {
 *         // Remember to exit backup mode, or the JE cleaner cannot delete
 *         // log files and disk usage will grow without bounds.
 *        backupHelper.endBackup();
 *     }
 * }
 *
 * void myDeleteUnusedFiles(File destDir, String[] filesInSnapshot) {
 *     // For each file in destDir that is NOT in filesInSnapshot, it should
 *     // be deleted from destDir to save disk space in the backup set, and to
 *     // ensure that unused files will not be restored.
 * }
 *
 * See myCopyFiles further above.
 * 
*

* When performing backups as shown in the first example above, to restore you * can simply copy all files from the backup set into an empty directory. *

* In the second example below, the list of current files is saved with the * backup set so it can be used during a restore. The backup set will * effectively hold multiple backups that can be used to restore to different * points in time. *

 * void myBackup(Environment env, File destDir) {
 *
 *     // Get the file number of the last file in the previous backup.
 *     long lastFileInPrevBackup =  ...
 *
 *     DbBackup backupHelper = new DbBackup(env, lastFileInPrevBackup);
 *
 *     // Optional: Do a checkpoint to reduce recovery time after a restore.
 *     env.checkpoint(new CheckpointConfig().setForce(true));
 *
 *     // Start backup, find out what needs to be copied.
 *     backupHelper.startBackup();
 *     try {
 *         // Copy the necessary files to archival storage.
 *         String[] filesToCopy = backupHelper.getLogFilesInBackupSet();
 *         myCopyFiles(env, backupHelper, filesToCopy, destDir);
 *
 *         // Save current list of files with backup data set.
 *         String[] filesInSnapshot = backupHelper.getLogFilesInSnapshot();
 *         // Save filesInSnapshot persistently here ...
 *
 *         // Update knowledge of last file saved in the backup set.
 *         lastFileInPrevBackup = backupHelper.getLastFileInBackupSet();
 *         // Save lastFileInPrevBackup persistently here ...
 *     } finally {
 *         // Remember to exit backup mode, or the JE cleaner cannot delete
 *         // log files and disk usage will grow without bounds.
 *        backupHelper.endBackup();
 *     }
 * }
 *
 * See myCopyFiles further above.
 * 
*

* When performing backups as shown in the second example above, to restore you * must choose one of the file lists that was saved. You may choose the list * written by the most recent backup, or a list written by an earlier backup. * To restore, the files in the list should be copied into an empty destination * directory. *

* Restoring from a backup *

* As described in the sections above, the restore procedure is to copy the * files from a backup set into an empty directory. Depending on the type of * backup that was performed (see above), either all files from the backup set * are copied, or only the files on a list that was created during the backup. *

* There is one additional consideration when performing a restore, under the * following condition: *

    *
  • Incremental backups are used, AND *
      *
    • the backup was created using DbBackup with JE 6.2 or earlier, * OR
    • *
    • the backup was created in a read-only JE environment.
    • *
    *
  • *
*

* If the above condition holds, after copying the files an additional step is * needed. To enable the creation of future incremental backups using the * restored files, the {@link * com.sleepycat.je.EnvironmentConfig#ENV_RECOVERY_FORCE_NEW_FILE} parameter * should be set to true when opening the JE Environment for the first time * after the restore. When this parameter is set to true, the last .jdb file * restored will not be modified when opening the Environment, and the next * .jdb file will be created and will become the end-of-log file. *

* WARNING: When the above special condition is true and this property is * not set to true when opening the environment for the first time * after a restore, then the backup set that was restored may not be used as * the basis for future incremental backups. If a future incremental backup * were performed based on this backup set, it would be incomplete and data * would be lost if that incremental backup were restored. *

* When JE 6.3 or later is used to create the backup, and the backup is created * in a read-write environment (the usual case), this extra step is * unnecessary. In this case, {@link #startBackup} will have added an * "immutable file" marker to the last file in the backup and this will prevent * that file from being modified, just as if the * {@code ENV_RECOVERY_FORCE_NEW_FILE} parameter were set to true. */ public class DbBackup { private final EnvironmentImpl envImpl; private final boolean envIsReadOnly; private final long firstFileInBackup; private long lastFileInBackup = -1; private boolean backupStarted; private boolean networkRestore; private ProtectedActiveFileSet protectedFileSet; private NavigableSet snapshotFiles; /* Status presents whether this back up is invalid because of roll back. */ private boolean invalid; /* The rollback start file number. */ private long rollbackStartedFileNumber; /* For unit tests. */ private TestHook testHook; /** * Creates a DbBackup helper for a full backup. * *

This is equivalent to using {@link #DbBackup(Environment,long)} and * passing {@code -1} for the {@code lastFileInPrevBackup} parameter.

* * @param env with an open, valid environment handle. If the environment * directory has read/write permissions, the environment handle must be * configured for read/write. * * @throws IllegalArgumentException if the environment directory has * read/write permissions, but the environment handle is not configured for * read/write. */ public DbBackup(Environment env) throws DatabaseException { this(env, -1); } /** * Creates a DbBackup helper for an incremental backup. * * @param env with an open, valid environment handle. If the environment * directory has read/write permissions, the environment handle must be * configured for read/write. * * @param lastFileInPrevBackup the last file in the previous backup set * when performing an incremental backup, or {@code -1} to perform a full * backup. The first file in this backup set will be the file following * {@code lastFileInPrevBackup}. * * @throws EnvironmentFailureException if an unexpected, internal or * environment-wide failure occurs. * * @throws IllegalArgumentException if the environment directory has * read/write permissions, but the environment handle is not configured for * read/write. */ public DbBackup(Environment env, long lastFileInPrevBackup) { this(env, DbInternal.getNonNullEnvImpl(env), lastFileInPrevBackup); } /** * @hidden * For internal use only. */ public DbBackup(EnvironmentImpl envImpl) { this(null, envImpl, -1); } /** * This is the true body of the DbBackup constructor. The env param may be * null when this class is used internally. */ private DbBackup(Environment env, EnvironmentImpl envImpl, long lastFileInPrevBackup) { /* Check that the Environment is open. */ if (env != null) { DbInternal.checkOpen(env); } this.envImpl = envImpl; /* * If the environment is writable, we need a r/w environment handle * in order to flip the file. */ envIsReadOnly = envImpl.getFileManager().checkEnvHomePermissions(true); if ((!envIsReadOnly) && envImpl.isReadOnly()) { throw new IllegalArgumentException ("Environment handle may not be read-only when directory " + "is read-write"); } firstFileInBackup = lastFileInPrevBackup + 1; } /** * Start backup mode in order to determine the definitive backup set needed * at this point in time. * *

This method determines the last file in the backup set, which is the * last log file in the environment at this point in time. Following this * method call, all new data will be written to other, new log files. In * other words, the last file in the backup set will not be modified after * this method returns.

* *

WARNING: After calling this method, deletion of log files in * the backup set by the JE log cleaner will be disabled until {@link * #endBackup()} is called. To prevent unbounded growth of disk usage, be * sure to call {@link #endBackup()} to re-enable log file deletion. * Additionally, the Environment can't be closed until endBackup() is * called. *

* * @throws com.sleepycat.je.rep.LogOverwriteException if a replication * operation is overwriting log files. The backup can not proceed because * files may be invalid. The backup may be attempted at a later time. * * @throws EnvironmentFailureException if an unexpected, internal or * environment-wide failure occurs. * * @throws IllegalStateException if a backup is already in progress * * */ public synchronized void startBackup() throws DatabaseException { if (backupStarted) { throw new IllegalStateException("startBackup was already called"); } /* Throw a LogOverwriteException if the Environment is rolling back. */ if (!envImpl.addDbBackup(this)) { throw envImpl.createLogOverwriteException ("A replication operation is overwriting log files. The " + "backup can not proceed because files may be invalid. The " + "backup may be attempted at a later time."); } final FileProtector fileProtector = envImpl.getFileProtector(); /* * For a network restore we use a different backup name/id and also * protect the 2 newest (highest numbered) reserved files. This is a * safeguard to ensure that the restored node can function as a master. * In a future release this approach may be improved by additionally * copying all reserved files to the restored node, but only after it * has recovered using the active files [#25783]. */ final long backupId = networkRestore ? envImpl.getNodeSequence().getNextNetworkRestoreId() : envImpl.getNodeSequence().getNextBackupId(); final String backupName = (networkRestore ? FileProtector.NETWORK_RESTORE_NAME : FileProtector.BACKUP_NAME) + "-" + backupId; final int nReservedFiles = networkRestore ? 2 : 0; /* * Protect all files from deletion momentarily, while determining the * last file and protecting the active files. */ final ProtectedFileRange allFilesProtected = fileProtector.protectFileRange(backupName + "-init", 0); try { /* * Abort file erasure before the file flip to ensure that files * are not modified during the backup or network restore. * FUTURE: We unconditionally abort any erasure in progress here * and therefore the abortErase param could be removed. */ envImpl.getDataEraser().abortErase(allFilesProtected); if (envIsReadOnly) { /* * All files are currently immutable, so the backup list is the * current set of files. However, we can't add a marker to the * last file in list, and therefore it will not be immutable * after being restored to a read-write directory (unless the * user sets ENV_RECOVERY_FORCE_NEW_FILE after restoring). */ lastFileInBackup = envImpl.getFileManager().getLastFileNum(); } else { /* * Flip the log so that all files in the backup list are * immutable. But first, write an "immutable file" marker in * the last file in the backup, so it cannot be modified after * it is restored. Recovery enforces this rule. */ LogEntry marker = new SingleItemEntry<>( LogEntryType.LOG_IMMUTABLE_FILE, new EmptyLogEntry()); long markerLsn = envImpl.getLogManager().log( marker, ReplicationContext.NO_REPLICATE); envImpl.forceLogFileFlip(); lastFileInBackup = DbLsn.getFileNumber(markerLsn); } /* * Protect all active files from deletion. This includes files * prior to firstFileInBackup, in order to get a snapshot of all * active files. New files do not need protection, since the backup * set does not include them. lastFileInBackup will be protected by * protectActiveFiles because it is not the last file in the env. */ protectedFileSet = fileProtector.protectActiveFiles( backupName, nReservedFiles, false /*protectNewFiles*/); } finally { fileProtector.removeFileProtection(allFilesProtected); } /* At this point, endBackup must be called to undo file protection. */ backupStarted = true; /* Files after lastFileInBackup do not need protection. */ protectedFileSet.truncateTail(lastFileInBackup); /* Snapshot the complete backup file set. */ snapshotFiles = protectedFileSet.getProtectedFiles(); /* * Now that we have the snapshot, files before firstFileInBackup do not * need protection. */ protectedFileSet.truncateHead(firstFileInBackup); } /** * End backup mode, thereby re-enabling normal deletion of log files by the * JE log cleaner. * * @throws com.sleepycat.je.rep.LogOverwriteException if a replication * operation has overwritten log files. Any copied files should be * considered invalid and discarded. The backup may be attempted at a * later time. * * @throws com.sleepycat.je.EnvironmentFailureException if an unexpected, * internal or environment-wide failure occurs. * * @throws IllegalStateException if a backup has not been started. */ public synchronized void endBackup() { checkBackupStarted(); backupStarted = false; assert TestHookExecute.doHookIfSet(testHook); envImpl.getFileProtector().removeFileProtection(protectedFileSet); envImpl.removeDbBackup(this); /* If this back up is invalid, throw a LogOverwriteException. */ if (invalid) { invalid = false; throw envImpl.createLogOverwriteException ("A replication operation has overwritten log files from " + "file " + rollbackStartedFileNumber + ". Any copied files " + "should be considered invalid and discarded. The backup " + "may be attempted at a later time."); } } /** * Can only be called in backup mode, after startBackup() has been called. * * @return the file number of the last file in the current backup set. * Save this value to reduce the number of files that must be copied at * the next backup session. * * @throws IllegalStateException if a backup has not been started. */ public synchronized long getLastFileInBackupSet() { checkBackupStarted(); return lastFileInBackup; } /** * Get the minimum list of files that must be copied for this backup. When * performing an incremental backup, this consists of the set of active * files that are greater than the last file copied in the previous backup * session. When performing a full backup, this consists of the set of all * active files. Can only be called in backup mode, after startBackup() has * been called. * *

The file numbers returned are in the range from the constructor * parameter {@code lastFileInPrevBackup + 1} to the last log file at the * time that {@link #startBackup} was called.

* * @return the names of all files to be copied, sorted in alphabetical * order. The return values are generally simple file names, not full * paths. However, if multiple data directories are being used (i.e. the * * je.log.nDataDirectories parameter is non-0), then the file names are * prepended with the associated "dataNNN/" prefix, where "dataNNN/" is * the data directory name within the environment home directory and "/" * is the relevant file separator for the platform. * * @throws EnvironmentFailureException if an unexpected, internal or * environment-wide failure occurs. * * @throws IllegalStateException if a backup has not been started. */ public synchronized String[] getLogFilesInBackupSet() { checkBackupStarted(); return getFileNames(snapshotFiles.tailSet(firstFileInBackup, true)); } /** * Get the minimum list of files that must be copied for this backup. This * consists of the set of active files that are greater than the last file * copied in the previous backup session. Can only be called in backup * mode, after startBackup() has been called. * * @param lastFileInPrevBackup file number of last file copied in the last * backup session, obtained from getLastFileInBackupSet(). * * @return the names of all the files to be copied that come after * lastFileInPrevBackup. * * @throws EnvironmentFailureException if an unexpected, internal or * environment-wide failure occurs. * * @throws IllegalStateException if a backup has not been started. * * @deprecated replaced by {@link #getLogFilesInBackupSet()}; pass * lastFileInPrevBackup to the {@link #DbBackup(Environment,long)} * constructor. */ @Deprecated public synchronized String[] getLogFilesInBackupSet( long lastFileInPrevBackup) { checkBackupStarted(); return getFileNames( snapshotFiles.tailSet(lastFileInPrevBackup + 1, true)); } /** * Get the list of all active files that are needed for the environment at * the point of time when backup mode started, i.e., the current snapshot. * Can only be called in backup mode, after startBackup() has been called. * *

When performing an incremental backup, this method is called to * determine the files that would needed for a restore. As described in * the examples at the top of this class, this list can be used to avoid * unused files after a restore, and may also be used to reduce the size of * the backup set.

* *

When performing a full backup this method is normally not needed, * since in that case it returns the same set of files that is returned by * {@link #getLogFilesInBackupSet()}.

* * @return the names of all files in the snapshot, sorted in alphabetical * order. The return values are generally simple file names, not full * paths. However, if multiple data directories are being used (i.e. the * * je.log.nDataDirectories parameter is non-0), then the file names are * prepended with the associated "dataNNN/" prefix, where "dataNNN/" is * the data directory name within the environment home directory and "/" * is the relevant file separator for the platform. * * @throws EnvironmentFailureException if an unexpected, internal or * environment-wide failure occurs. * * @throws IllegalStateException if a backup has not been started. */ public synchronized String[] getLogFilesInSnapshot() { checkBackupStarted(); return getFileNames(snapshotFiles); } private String[] getFileNames(NavigableSet fileSet) { final FileManager fileManager = envImpl.getFileManager(); final String[] names = new String[fileSet.size()]; int i = 0; for (Long file : fileSet) { names[i] = fileManager.getPartialFileName(file); i += 1; } return names; } /** * Removes protection for a file in the backup set. This method should be * called after copying a file, so that it may be deleted to avoid * exceeding disk usage limits. * * @param fileName a file name that has already been copied, in the format * returned by {@link #getLogFilesInBackupSet} . * * @since 7.5 */ public synchronized void removeFileProtection(String fileName) { checkBackupStarted(); protectedFileSet.removeFile( envImpl.getFileManager().getNumFromName(fileName)); } private void checkBackupStarted() { if (!backupStarted) { throw new IllegalStateException("startBackup was not called"); } } /** * For internal use only. * @hidden * Returns true if a backup has been started and is in progress. */ public synchronized boolean backupIsOpen() { return backupStarted; } /** * For internal use only. * @hidden * * Invalidate this backup if replication overwrites the log. */ public void invalidate(long fileNumber) { invalid = true; this.rollbackStartedFileNumber = fileNumber; } /** * For internal use only. * @hidden * * Marks this backup as a network restore. Causes the protected file set * name/id to be set specially, and two reserved files to be included. * See {@link #startBackup()}. * * Another approach (for future consideration) is to factor out the part * of DbBackup that is needed by network restore into utility methods, * so that special code for network restore can be removed from DbBackup. * The shared portion should be just the startBackup code. */ public void setNetworkRestore() { networkRestore = true; } /** * For internal use only. * @hidden * * A test entry point used to simulate the environment is now rolling back, * and this TestHook would invalidate the in progress DbBackups. */ public void setTestHook(TestHook testHook) { this.testHook = testHook; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy