summaryrefslogtreecommitdiff
path: root/src/main/java/com/amazon/carbonado/repo/sleepycat
diff options
context:
space:
mode:
authorBrian S. O'Neill <bronee@gmail.com>2010-05-16 17:11:36 +0000
committerBrian S. O'Neill <bronee@gmail.com>2010-05-16 17:11:36 +0000
commit1a00850ce21cfae75e9706baa23989744f534df3 (patch)
treee58f61a5697d23a4f22e449e4234584d29eb803f /src/main/java/com/amazon/carbonado/repo/sleepycat
parent4cc824245c96d6caad657ea798974da0751c956b (diff)
Comments and compatibility for new backup features.
Diffstat (limited to 'src/main/java/com/amazon/carbonado/repo/sleepycat')
-rw-r--r--src/main/java/com/amazon/carbonado/repo/sleepycat/BDBRepository.java268
-rw-r--r--src/main/java/com/amazon/carbonado/repo/sleepycat/HotBackupCapability.java84
2 files changed, 191 insertions, 161 deletions
diff --git a/src/main/java/com/amazon/carbonado/repo/sleepycat/BDBRepository.java b/src/main/java/com/amazon/carbonado/repo/sleepycat/BDBRepository.java
index ed90278..27b4109 100644
--- a/src/main/java/com/amazon/carbonado/repo/sleepycat/BDBRepository.java
+++ b/src/main/java/com/amazon/carbonado/repo/sleepycat/BDBRepository.java
@@ -159,7 +159,7 @@ abstract class BDBRepository<Txn> extends AbstractRepository<Txn>
mRunCheckpointer = !builder.getReadOnly() && builder.getRunCheckpointer();
mKeepOldLogFiles = builder.getKeepOldLogFiles();
- mLogInMemory = builder.getLogInMemory();
+ mLogInMemory = builder.getLogInMemory();
mRunDeadlockDetector = builder.getRunDeadlockDetector();
mStorableCodecFactory = builder.getStorableCodecFactory();
mPreShutdownHook = builder.getPreShutdownHook();
@@ -221,57 +221,66 @@ abstract class BDBRepository<Txn> extends AbstractRepository<Txn>
@Override
public Backup startBackup() throws RepositoryException {
- return startBackup(false);
+ return startBackup(false);
}
@Override
public Backup startBackup(boolean deleteOldLogFiles) throws RepositoryException {
- if (mLogInMemory) {
- throw new IllegalStateException("Log files are only kept in memory and backups cannot be performed");
- }
+ if (mLogInMemory) {
+ throw new IllegalStateException
+ ("Log files are only kept in memory and backups cannot be performed");
+ }
synchronized (mBackupLock) {
int count = mBackupCount;
if (count == 0) {
try {
- enterBackupMode(deleteOldLogFiles);
+ if (deleteOldLogFiles) {
+ // TODO: If backup rejects log deletion, queue up for later.
+ enterBackupMode(true);
+ } else {
+ // Call old API for backwards compatibility.
+ enterBackupMode();
+ }
} catch (Exception e) {
throw mExTransformer.toRepositoryException(e);
}
}
mBackupCount = count + 1;
- return new FullBackup();
+ return new FullBackup();
}
}
@Override
public Backup startIncrementalBackup(long lastLogNumber)
- throws RepositoryException
+ throws RepositoryException
{
- return startIncrementalBackup(lastLogNumber, false);
+ return startIncrementalBackup(lastLogNumber, false);
}
@Override
public Backup startIncrementalBackup(long lastLogNumber, boolean deleteOldLogFiles)
- throws RepositoryException
+ throws RepositoryException
{
- if (mLogInMemory) {
- throw new IllegalStateException("Log files are only kept in memory and incremental backup cannot be performed");
- }
-
- if (lastLogNumber < 0) {
- throw new IllegalArgumentException("The number of the last backup cannot be negative");
- }
- synchronized (mBackupLock) {
- try {
- enterIncrementalBackupMode(lastLogNumber, deleteOldLogFiles);
- ++mIncrementalBackupCount;
- } catch (Exception e) {
- throw mExTransformer.toRepositoryException(e);
- }
- }
- return new IncrementalBackup(lastLogNumber);
+ if (mLogInMemory) {
+ throw new IllegalStateException
+ ("Log files are only kept in memory and incremental backup cannot be performed");
+ }
+
+ if (lastLogNumber < 0) {
+ throw new IllegalArgumentException
+ ("The number of the last backup cannot be negative: " + lastLogNumber);
+ }
+ synchronized (mBackupLock) {
+ try {
+ enterIncrementalBackupMode(lastLogNumber, deleteOldLogFiles);
+ ++mIncrementalBackupCount;
+ } catch (Exception e) {
+ throw mExTransformer.toRepositoryException(e);
+ }
+ }
+ return new IncrementalBackup(lastLogNumber);
}
/**
@@ -664,6 +673,14 @@ abstract class BDBRepository<Txn> extends AbstractRepository<Txn>
throws Exception;
/**
+ * Called only the first time a backup is started. Old API is kept for
+ * backwards compatibility.
+ */
+ void enterBackupMode() throws Exception {
+ enterBackupMode(false);
+ }
+
+ /**
* Called only the first time a backup is started.
*/
abstract void enterBackupMode(boolean deleteOldLogFiles) throws Exception;
@@ -676,7 +693,8 @@ abstract class BDBRepository<Txn> extends AbstractRepository<Txn>
/**
* Called only when an incremental backup is started.
*/
- abstract void enterIncrementalBackupMode(long lastLogNumber, boolean deleteOldLogFiles) throws Exception;
+ abstract void enterIncrementalBackupMode(long lastLogNumber, boolean deleteOldLogFiles)
+ throws Exception;
/**
* Called only after incremental backup ends.
@@ -684,6 +702,14 @@ abstract class BDBRepository<Txn> extends AbstractRepository<Txn>
abstract void exitIncrementalBackupMode() throws Exception;
/**
+ * Called only if in backup mode. Old API is kept for backwards
+ * compatibility.
+ */
+ File[] backupFiles() throws Exception {
+ return backupFiles(new long[1]);
+ }
+
+ /**
* Called only if in backup mode.
*
* @param newLastLogNum reference to last log number at [0]
@@ -914,100 +940,106 @@ abstract class BDBRepository<Txn> extends AbstractRepository<Txn>
}
abstract class AbstractBackup implements Backup {
- boolean mDone;
- long mFinalLogNumber;
-
- AbstractBackup() {
- mFinalLogNumber = -1;
- }
-
- @Override
- public void endBackup() throws RepositoryException {
- synchronized (mBackupLock) {
- if (mDone) {
- return;
- }
- mDone = true;
- finishBackup();
- }
- }
-
- @Override
- public File[] getFiles() throws RepositoryException {
- synchronized (mBackupLock) {
- if (mDone) {
- throw new IllegalStateException("Backup has ended");
- }
-
- try {
- long[] newLastLogNum = {-1};
- File[] toReturn = getBackupFiles(newLastLogNum);
- mFinalLogNumber = newLastLogNum[0];
- return toReturn;
- } catch (Exception e) {
- throw mExTransformer.toRepositoryException(e);
- }
- }
- }
-
- @Override
- public long getLastLogNumber() throws RepositoryException {
- if (mFinalLogNumber < 0) {
- throw new IllegalStateException("Must get files prior to retrieving the last log number");
- }
- return mFinalLogNumber;
- }
-
- abstract void finishBackup() throws RepositoryException;
-
- abstract File[] getBackupFiles(long[] newLastLogNum) throws Exception;
+ boolean mDone;
+ long mFinalLogNumber;
+
+ AbstractBackup() {
+ mFinalLogNumber = -1;
+ }
+
+ @Override
+ public void endBackup() throws RepositoryException {
+ synchronized (mBackupLock) {
+ if (mDone) {
+ return;
+ }
+ mDone = true;
+ finishBackup();
+ }
+ }
+
+ @Override
+ public File[] getFiles() throws RepositoryException {
+ synchronized (mBackupLock) {
+ if (mDone) {
+ throw new IllegalStateException("Backup has ended");
+ }
+
+ try {
+ long[] newLastLogNum = {-1};
+ File[] toReturn = getBackupFiles(newLastLogNum);
+ mFinalLogNumber = newLastLogNum[0];
+ return toReturn;
+ } catch (Exception e) {
+ throw mExTransformer.toRepositoryException(e);
+ }
+ }
+ }
+
+ @Override
+ public long getLastLogNumber() throws RepositoryException {
+ if (mFinalLogNumber < 0) {
+ throw new IllegalStateException
+ ("Must get files prior to retrieving the last log number");
+ }
+ return mFinalLogNumber;
+ }
+
+ abstract void finishBackup() throws RepositoryException;
+
+ abstract File[] getBackupFiles(long[] newLastLogNum) throws Exception;
}
class IncrementalBackup extends AbstractBackup {
- private final long mLastLogNumber;
-
- IncrementalBackup(long lastLogNumber) {
- super();
- mLastLogNumber = lastLogNumber;
- }
-
- @Override
- public void finishBackup() throws RepositoryException {
- --mIncrementalBackupCount;
-
- try {
- exitIncrementalBackupMode();
- } catch (Exception e) {
- throw mExTransformer.toRepositoryException(e);
- }
- }
-
- @Override
- public File[] getBackupFiles(long[] newLastLogNum) throws Exception {
- return incrementalBackup(mLastLogNumber, newLastLogNum);
- }
+ private final long mLastLogNumber;
+
+ IncrementalBackup(long lastLogNumber) {
+ super();
+ mLastLogNumber = lastLogNumber;
+ }
+
+ @Override
+ void finishBackup() throws RepositoryException {
+ --mIncrementalBackupCount;
+
+ try {
+ exitIncrementalBackupMode();
+ } catch (Exception e) {
+ throw mExTransformer.toRepositoryException(e);
+ }
+ }
+
+ @Override
+ File[] getBackupFiles(long[] newLastLogNum) throws Exception {
+ return incrementalBackup(mLastLogNumber, newLastLogNum);
+ }
}
class FullBackup extends AbstractBackup {
- @Override
- void finishBackup() throws RepositoryException {
- int count = mBackupCount - 1;
- try {
- if (count == 0) {
- try {
- exitBackupMode();
- } catch (Exception e) {
- throw mExTransformer.toRepositoryException(e);
- }
- }
- } finally {
- mBackupCount = count;
- }
- }
-
- @Override
- public File[] getBackupFiles(long[] newLastLogNum) throws Exception {
- return backupFiles(newLastLogNum);
- }
- }
-} \ No newline at end of file
+ @Override
+ void finishBackup() throws RepositoryException {
+ int count = mBackupCount - 1;
+ try {
+ if (count == 0) {
+ try {
+ exitBackupMode();
+ } catch (Exception e) {
+ throw mExTransformer.toRepositoryException(e);
+ }
+ }
+ } finally {
+ mBackupCount = count;
+ }
+ }
+
+ @Override
+ File[] getBackupFiles(long[] newLastLogNum) throws Exception {
+ try {
+ return backupFiles(newLastLogNum);
+ } catch (AbstractMethodError e) {
+ // Call old API for backwards compatibility.
+ return backupFiles();
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/amazon/carbonado/repo/sleepycat/HotBackupCapability.java b/src/main/java/com/amazon/carbonado/repo/sleepycat/HotBackupCapability.java
index 76cfb7e..05d8a6d 100644
--- a/src/main/java/com/amazon/carbonado/repo/sleepycat/HotBackupCapability.java
+++ b/src/main/java/com/amazon/carbonado/repo/sleepycat/HotBackupCapability.java
@@ -25,32 +25,28 @@ import com.amazon.carbonado.RepositoryException;
import com.amazon.carbonado.capability.Capability;
/**
- * Capability for performing a backup of an active BDB environment. To restore
- * from a hot backup, it is <b>critical</b> that a full recovery be
- * performed. BDB-JE does not require this, however. Pass true to {@link
- * BDBRepositoryBuilder#setRunFullRecovery(boolean)} to enable.
+ * Capability for performing a backup of an active BDB environment. If {@link
+ * BDBRepositoryBuilder#setLogInMemory(boolean) in-memory logging} is enabled,
+ * backups cannot be performed. To restore from a hot backup, it is
+ * <b>critical</b> that a full recovery be performed. Pass true to {@link
+ * BDBRepositoryBuilder#setRunFullRecovery(boolean) setRunFullRecovery} to
+ * enable. {@link BDBProduct#JE BDB-JE} does not require this, however.
*
- * <p>
- * If incremental backups are performed it is required that
- * log file removal is disabled in the underlying database.
+ * <p>To support incremental backups against the {@link BDBProduct#DB native
+ * BDB product}, old log files must be kept. Pass true to {@link
+ * BDBRepositoryBuilder#setKeepOldLogFiles(boolean) setKeepOldLogFiles}.
*
* @author Brian S O'Neill
* @author Olga Kuznetsova
* @since 1.2.1
*/
public interface HotBackupCapability extends Capability {
-///TODO:Have log file deletion be queued after all backups are completed
/**
* Starts the backup by disabling log file deletion. Be sure to call
* endBackup when done to resume log file cleanup. Concurrent backups are
* supported.
*
- * <p>
- * To perform incremental backups use the builder option of setLogInMemory(false)
- * so that old log files are not deleted. Log files can be deleted in the
- * future before starting a new backup (see method below).
- *
- * @throws IllegalStateException if log files are being removed (setLogInMemory(true))
+ * @throws IllegalStateException if configuration doesn't support backups
*/
Backup startBackup() throws RepositoryException;
@@ -58,23 +54,24 @@ public interface HotBackupCapability extends Capability {
* Starts the backup by disabling log file deletion. Be sure to call
* endBackup when done to resume log file cleanup. Concurrent backups are supported.
*
- * <p>
- * Caution should be observed when deleting old log files by force as log files as they may be required
- * for future incremental backups (if concurrent backups are running).
- * If any concurrent backups are occurring, log fail deletion will fail.
+ * <p>Caution should be observed when deleting old log files by force, if
+ * an external process is also performing backups. If a concurrent backup
+ * is issued by this repository instance, log file deletion is suppressed.
*
- * @param deleteOldLogFiles deletes log files that are no longer in use and have been backed up. False by default.
- * @throws IllegalStateException if log files are being removed (setLogInMemory(true))
+ * @param deleteOldLogFiles deletes log files that are no longer in use and
+ * have been backed up. False by default.
+ * @throws IllegalStateException if configuration doesn't support backups
*/
Backup startBackup(boolean deleteOldLogFiles) throws RepositoryException;
/**
- * Starts an incremental backup. Log files that are newer than the lastLogNumber will be copied
- * during the backup. Should only be run after performing a full backup.
+ * Starts an incremental backup. Log files that are newer than the
+ * lastLogNumber will be copied during the backup. Should only be run after
+ * performing a full backup.
*
- * @param lastLogNumber number of the last log file that was copied in a previous backup.
+ * @param lastLogNumber number of the last log file that was copied in a previous backup
* @throws IllegalArgumentException if lastLogNumber is negative
- * @throws IllegalStateException if log files are being removed (setLogInMemory(true))
+ * @throws IllegalStateException if configuration doesn't support backups
*/
Backup startIncrementalBackup(long lastLogNumber) throws RepositoryException;
@@ -82,43 +79,44 @@ public interface HotBackupCapability extends Capability {
* Starts an incremental backup. Log files that are newer than the lastLogNumber will be copied
* during the backup. Can only be run after performing a full backup.
*
- * <p>
- * Caution should be observed when deleting old log files by force as log files as they may be required
- * for future incremental backups (if concurrent backups are running).
- * If any concurrent backups are occurring, log fail deletion will fail.
+ * <p>Caution should be observed when deleting old log files by force, if
+ * an external process is also performing backups. If a concurrent backup
+ * is issued by this repository instance, log file deletion is suppressed.
*
* @param lastLogNumber number of the last log file that was copied in a previous backup.
- * @param deleteOldLogFiles deletes log files that are no longer in use and have been backed up. False by default.
+ * @param deleteOldLogFiles deletes log files that are no longer in use and
+ * have been backed up. False by default.
* @throws IllegalArgumentException if lastLogNumber is negative
- * @throws IllegalStateException if log files are being removed (setLogInMemory(true))
+ * @throws IllegalStateException if configuration doesn't support backups
*/
- Backup startIncrementalBackup(long lastLogNumber, boolean deleteOldLogFiles) throws RepositoryException;
+ Backup startIncrementalBackup(long lastLogNumber, boolean deleteOldLogFiles)
+ throws RepositoryException;
public static interface Backup {
/**
- * Resume normal operation.
+ * Resume normal operation.
*/
void endBackup() throws RepositoryException;
/**
* Returns all the files to be copied, in the exact order in which they
* must be copied.
- *
- * <p>
- * These files must be copied prior to calling endBackup().
+ *
+ * <p>These files must be durably copied prior to calling {@link #endBackup()}.
*
* @return ordered array of absolute files
* @throws IllegalStateException if backup has ended
*/
File[] getFiles() throws RepositoryException;
- /**
- * Can be called after a backup has been performed to find the last log file
- * that has been backed up.
- *
- * @return the file number of the last file in the current backup set.
- * This number is required to perform incremental backups.
- */
- long getLastLogNumber() throws RepositoryException;
+ /**
+ * Can be called after a backup has been performed to find the last log file
+ * that has been backed up.
+ *
+ * @return the file number of the last file in the current backup set.
+ * This number is required to perform incremental backups.
+ * @throws IllegalStateException if {@link #getFiles()} was not called
+ */
+ long getLastLogNumber() throws RepositoryException;
}
}