summaryrefslogtreecommitdiff
path: root/src/main/java/com/amazon/carbonado/repo
diff options
context:
space:
mode:
authorBrian S. O'Neill <bronee@gmail.com>2009-03-17 02:00:09 +0000
committerBrian S. O'Neill <bronee@gmail.com>2009-03-17 02:00:09 +0000
commit2f4a6a755cd34e929faf55daacb8f69fdde6be43 (patch)
tree5396ae0ca5c0209aa1529e2ca76d2e0f2839f97d /src/main/java/com/amazon/carbonado/repo
parent1b82649d84c1f1d233952625f7149d64fb68bc2b (diff)
Added capability to perform hot backups.
Diffstat (limited to 'src/main/java/com/amazon/carbonado/repo')
-rw-r--r--src/main/java/com/amazon/carbonado/repo/sleepycat/BDBRepository.java98
-rw-r--r--src/main/java/com/amazon/carbonado/repo/sleepycat/CheckpointCapability.java7
-rw-r--r--src/main/java/com/amazon/carbonado/repo/sleepycat/HotBackupCapability.java56
3 files changed, 157 insertions, 4 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 9f3d9ac..01e3668 100644
--- a/src/main/java/com/amazon/carbonado/repo/sleepycat/BDBRepository.java
+++ b/src/main/java/com/amazon/carbonado/repo/sleepycat/BDBRepository.java
@@ -83,6 +83,7 @@ abstract class BDBRepository<Txn> extends AbstractRepository<Txn>
implements Repository,
RepositoryAccess,
IndexInfoCapability,
+ HotBackupCapability,
CheckpointCapability,
EnvironmentCapability,
ShutdownCapability,
@@ -116,6 +117,9 @@ abstract class BDBRepository<Txn> extends AbstractRepository<Txn>
final String mSingleFileName;
final Map<String, String> mFileNameMap;
+ final Object mBackupLock = new Object();
+ int mBackupCount = 0;
+
private LayoutFactory mLayoutFactory;
private LobEngine mLobEngine;
@@ -221,6 +225,63 @@ abstract class BDBRepository<Txn> extends AbstractRepository<Txn>
return StorableIntrospector.examine(type).getAllProperties().get(name) != null;
}
+ @Override
+ public Backup startBackup() throws RepositoryException {
+ synchronized (mBackupLock) {
+ int count = mBackupCount;
+ if (count == 0) {
+ try {
+ enterBackupMode();
+ } catch (Exception e) {
+ throw mExTransformer.toRepositoryException(e);
+ }
+ }
+ mBackupCount = count + 1;
+
+ return new Backup() {
+ private boolean mDone;
+
+ @Override
+ public void endBackup() throws RepositoryException {
+ synchronized (mBackupLock) {
+ if (mDone) {
+ return;
+ }
+ mDone = true;
+
+ int count = mBackupCount - 1;
+ try {
+ if (count == 0) {
+ try {
+ exitBackupMode();
+ } catch (Exception e) {
+ throw mExTransformer.toRepositoryException(e);
+ }
+ }
+ } finally {
+ mBackupCount = count;
+ }
+ }
+ }
+
+ @Override
+ public File[] getFiles() throws RepositoryException {
+ synchronized (mBackupLock) {
+ if (mDone) {
+ throw new IllegalStateException("Backup has ended");
+ }
+
+ try {
+ return backupFiles();
+ } catch (Exception e) {
+ throw mExTransformer.toRepositoryException(e);
+ }
+ }
+ }
+ };
+ }
+ }
+
/**
* Suspend the checkpointer until the suspension time has expired or until
* manually resumed. If a checkpoint is in progress, this method will block
@@ -365,6 +426,28 @@ abstract class BDBRepository<Txn> extends AbstractRepository<Txn>
return mIsMaster;
}
+ String[] getAllDatabaseNames() throws RepositoryException {
+ Repository metaRepo = getRootRepository();
+
+ Cursor<StoredDatabaseInfo> cursor =
+ metaRepo.storageFor(StoredDatabaseInfo.class)
+ .query().orderBy("databaseName").fetch();
+
+ ArrayList<String> names = new ArrayList<String>();
+ // This one needs to manually added since it is the metadata db itself.
+ names.add(StoredDatabaseInfo.class.getName());
+
+ try {
+ while (cursor.hasNext()) {
+ names.add(cursor.next().getDatabaseName());
+ }
+ } finally {
+ cursor.close();
+ }
+
+ return names.toArray(new String[names.size()]);
+ }
+
String getDatabaseFileName(final String dbName) {
String singleFileName = mSingleFileName;
if (singleFileName == null && mFileNameMap != null) {
@@ -527,6 +610,21 @@ abstract class BDBRepository<Txn> extends AbstractRepository<Txn>
abstract <S extends Storable> BDBStorage<Txn, S> createBDBStorage(Class<S> type)
throws Exception;
+ /**
+ * Called only the first time a backup is started.
+ */
+ abstract void enterBackupMode() throws Exception;
+
+ /**
+ * Called only after the last backup ends.
+ */
+ abstract void exitBackupMode() throws Exception;
+
+ /**
+ * Called only if in backup mode.
+ */
+ abstract File[] backupFiles() throws Exception;
+
FetchException toFetchException(Throwable e) {
return mExTransformer.toFetchException(e);
}
diff --git a/src/main/java/com/amazon/carbonado/repo/sleepycat/CheckpointCapability.java b/src/main/java/com/amazon/carbonado/repo/sleepycat/CheckpointCapability.java
index dc4b3d7..c261d8a 100644
--- a/src/main/java/com/amazon/carbonado/repo/sleepycat/CheckpointCapability.java
+++ b/src/main/java/com/amazon/carbonado/repo/sleepycat/CheckpointCapability.java
@@ -22,9 +22,10 @@ import com.amazon.carbonado.PersistException;
import com.amazon.carbonado.capability.Capability;
/**
- * Capability to control BDB checkpointing. Useful when performing hot backups.
+ * Capability to control BDB checkpointing.
*
* @author Brian S O'Neill
+ * @see HotBackupCapability
*/
public interface CheckpointCapability extends Capability {
/**
@@ -33,9 +34,7 @@ public interface CheckpointCapability extends Capability {
* until it is finished. If checkpointing is disabled, calling this method
* has no effect.
*
- * <p>Calling this method repeatedly resets the suspension time. This
- * technique should be used by hot backup processes to ensure that its
- * failure does not leave the checkpointer permanently suspended. Each
+ * <p>Calling this method repeatedly resets the suspension time. Each
* invocation of suspendCheckpointer is like a lease renewal or heartbeat.
*
* @param suspensionTime minimum length of suspension, in milliseconds,
diff --git a/src/main/java/com/amazon/carbonado/repo/sleepycat/HotBackupCapability.java b/src/main/java/com/amazon/carbonado/repo/sleepycat/HotBackupCapability.java
new file mode 100644
index 0000000..8bce86d
--- /dev/null
+++ b/src/main/java/com/amazon/carbonado/repo/sleepycat/HotBackupCapability.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2009 Amazon Technologies, Inc. or its affiliates.
+ * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks
+ * of Amazon Technologies, Inc. or its affiliates. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.amazon.carbonado.repo.sleepycat;
+
+import java.io.File;
+
+import com.amazon.carbonado.RepositoryException;
+
+import com.amazon.carbonado.capability.Capability;
+
+/**
+ * Capability for performing a backup of an active BDB environment.
+ *
+ * @author Brian S O'Neill
+ * @since 1.2.1
+ */
+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 is
+ * supported.
+ */
+ Backup startBackup() throws RepositoryException;
+
+ public static interface Backup {
+ /**
+ * End the backup and resume log file cleanup.
+ */
+ void endBackup() throws RepositoryException;
+
+ /**
+ * Returns all the files to be copied, in the exact order in which they
+ * must be copied.
+ *
+ * @return ordered array of absolute files
+ * @throws IllegalStateException if backup has ended
+ */
+ File[] getFiles() throws RepositoryException;
+ }
+}