From 2f4a6a755cd34e929faf55daacb8f69fdde6be43 Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Tue, 17 Mar 2009 02:00:09 +0000 Subject: Added capability to perform hot backups. --- .../carbonado/repo/sleepycat/BDBRepository.java | 98 ++++++++++++++++++++++ .../repo/sleepycat/CheckpointCapability.java | 7 +- .../repo/sleepycat/HotBackupCapability.java | 56 +++++++++++++ 3 files changed, 157 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/amazon/carbonado/repo/sleepycat/HotBackupCapability.java (limited to 'src/main') 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 extends AbstractRepository implements Repository, RepositoryAccess, IndexInfoCapability, + HotBackupCapability, CheckpointCapability, EnvironmentCapability, ShutdownCapability, @@ -116,6 +117,9 @@ abstract class BDBRepository extends AbstractRepository final String mSingleFileName; final Map mFileNameMap; + final Object mBackupLock = new Object(); + int mBackupCount = 0; + private LayoutFactory mLayoutFactory; private LobEngine mLobEngine; @@ -221,6 +225,63 @@ abstract class BDBRepository extends AbstractRepository 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 extends AbstractRepository return mIsMaster; } + String[] getAllDatabaseNames() throws RepositoryException { + Repository metaRepo = getRootRepository(); + + Cursor cursor = + metaRepo.storageFor(StoredDatabaseInfo.class) + .query().orderBy("databaseName").fetch(); + + ArrayList names = new ArrayList(); + // 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 extends AbstractRepository abstract BDBStorage createBDBStorage(Class 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. * - *

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 + *

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; + } +} -- cgit v1.2.3