From fa817e5a12f1b0ee574272fe711ed1a96f2b3595 Mon Sep 17 00:00:00 2001
From: Fabio Pistolesi <fabio.pistolesi@forgerock.com>
Date: Fri, 06 Feb 2015 14:51:35 +0000
Subject: [PATCH] OPENDJ-1750 CR-5916 Backup of a Persistit backend generates empty backup set Fixes the "Empty backup" problem when creating a backup of a pluggable backend. Uses CR-5915 preparatory work to propagate storage information to the backupConfig, to correctly decide which files should belong to a backup. Thanks JN!
---
opendj3-server-dev/src/server/org/opends/server/backends/persistit/PersistItStorage.java | 16 +++++
opendj3-server-dev/src/server/org/opends/server/backends/pluggable/BackupManager.java | 43 ++++++--------
opendj3-server-dev/src/server/org/opends/server/types/BackupConfig.java | 65 +++++++++++++++++----
opendj3-server-dev/src/server/org/opends/server/backends/pluggable/spi/Storage.java | 7 ++
opendj3-server-dev/src/server/org/opends/server/backends/pluggable/BackendImpl.java | 4
5 files changed, 94 insertions(+), 41 deletions(-)
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/persistit/PersistItStorage.java b/opendj3-server-dev/src/server/org/opends/server/backends/persistit/PersistItStorage.java
index bee6283..7ab9291 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/persistit/PersistItStorage.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/persistit/PersistItStorage.java
@@ -27,11 +27,11 @@
import static com.persistit.Transaction.CommitPolicy.*;
import static java.util.Arrays.*;
-
import static org.opends.messages.JebMessages.*;
import static org.opends.server.util.StaticUtils.*;
import java.io.File;
+import java.io.FilenameFilter;
import java.util.HashMap;
import java.util.Map;
@@ -686,6 +686,20 @@
}
}
+ /** {@inheritDoc} */
+ @Override
+ public FilenameFilter getFilesToBackupFilter()
+ {
+ return new FilenameFilter()
+ {
+ @Override
+ public boolean accept(File d, String name)
+ {
+ return name.startsWith(VOLUME_NAME) && !name.endsWith(".lck");
+ }
+ };
+ }
+
/*
* TODO: it would be nice to use the low-level key/value APIs. They seem quite
* inefficient at the moment for simple byte arrays.
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/BackendImpl.java b/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/BackendImpl.java
index 82af2ca..1c6a0cf 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/BackendImpl.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/BackendImpl.java
@@ -759,8 +759,8 @@
BackupManager backupManager = new BackupManager(getBackendID());
File parentDir = getFileForPath(cfg.getDBDirectory());
File backendDir = new File(parentDir, cfg.getBackendId());
- // Storage storage = newStorageInstance();
- // backupConfig.setFilesToBackupFilter(storage.getFilesToBackupFilter());
+ Storage storage = newStorageInstance();
+ backupConfig.setFilesToBackupFilter(storage.getFilesToBackupFilter());
backupManager.createBackup(backendDir, backupConfig);
}
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/BackupManager.java b/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/BackupManager.java
index 3c079e5..16411d1 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/BackupManager.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/BackupManager.java
@@ -61,7 +61,7 @@
import org.opends.server.util.StaticUtils;
/**
- * A backup manager for JE backends.
+ * A backup manager for backends.
*/
public class BackupManager
{
@@ -106,7 +106,7 @@
/**
- * Construct a backup manager for a JE backend.
+ * Construct a backup manager for a backend.
* @param backendID The ID of the backend instance for which a backup
* manager is required.
*/
@@ -116,11 +116,11 @@
}
/**
- * Create a backup of the JE backend. The backup is stored in a single zip
+ * Create a backup of the backend. The backup is stored in a single zip
* file in the backup directory. If the backup is incremental, then the
- * first entry in the zip is a text file containing a list of all the JE
+ * first entry in the zip is a text file containing a list of all the
* log files that are unchanged since the previous backup. The remaining
- * zip entries are the JE log files themselves, which, for an incremental,
+ * zip entries are the log files themselves, which, for an incremental,
* only include those files that have changed.
* @param backendDir The directory of the backend instance for
* which the backup is required.
@@ -139,6 +139,7 @@
boolean encrypt = backupConfig.encryptData();
boolean hash = backupConfig.hashData();
boolean signHash = backupConfig.signHash();
+ FilenameFilter filenameFilter = backupConfig.getFilesToBackupFilter();
HashMap<String,String> backupProperties = new HashMap<String,String>();
@@ -321,17 +322,8 @@
zipStream.setLevel(Deflater.NO_COMPRESSION);
}
- // Get a list of all the log files comprising the database.
- FilenameFilter filenameFilter = new FilenameFilter()
- {
- @Override
- public boolean accept(File d, String name)
- {
- return name.endsWith(".jdb");
- }
- };
-
File[] logFiles;
+
try
{
logFiles = backendDir.listFiles(filenameFilter);
@@ -367,7 +359,7 @@
// Sort the log files from oldest to youngest since this is the order
// in which they must be copied.
- // This is easy since the files are created in alphabetical order by JE.
+ // This is easy since the files are created in alphabetical order.
Arrays.sort(logFiles);
try
@@ -464,8 +456,7 @@
been written to new log files, so we must include those new files.
*/
final String latest = logFiles[logFiles.length-1].getName();
- FilenameFilter filter = new JELatestFileFilter(latest,
- latestFileSize);
+ FilenameFilter filter = new DBLatestFileFilter(latest, latestFileSize, filenameFilter);
try
{
@@ -581,7 +572,7 @@
/**
- * Restore a JE backend from backup, or verify the backup.
+ * Restore a backend from backup, or verify the backup.
* @param backendDir The configuration of the backend instance to be
* restored.
* @param restoreConfig The configuration to use when performing the restore.
@@ -1236,22 +1227,26 @@
}
/**
- * This class implements a FilenameFilter to detect the last file
- * from a JE database.
+ * This class implements a FilenameFilter to detect the last file from a database.
*/
- private static class JELatestFileFilter implements FilenameFilter {
+ private static class DBLatestFileFilter implements FilenameFilter {
private final String latest;
private final long latestSize;
+ private FilenameFilter filenameFilter;
- public JELatestFileFilter(String latest, long latestSize) {
+ public DBLatestFileFilter(String latest, long latestSize, FilenameFilter filenameFilter) {
this.latest = latest;
this.latestSize = latestSize;
+ this.filenameFilter = filenameFilter;
}
@Override
public boolean accept(File d, String name)
{
- if (!name.endsWith(".jdb")) return false;
+ if (!filenameFilter.accept(d, name))
+ {
+ return false;
+ }
int compareTo = name.compareTo(latest);
return compareTo > 0 || compareTo == 0 && d.length() > latestSize;
}
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/spi/Storage.java b/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/spi/Storage.java
index c31844e..2d82a69 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/spi/Storage.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/spi/Storage.java
@@ -26,6 +26,7 @@
package org.opends.server.backends.pluggable.spi;
import java.io.Closeable;
+import java.io.FilenameFilter;
import org.opends.server.admin.std.server.PluggableBackendCfg;
@@ -105,6 +106,12 @@
*/
boolean isValid();
+ /**
+ * Returns a filename filter which selects the files to be included in a backup.
+ * @return a filename filter which selects the files to be included in a backup
+ */
+ FilenameFilter getFilesToBackupFilter();
+
/** {@inheritDoc} */
@Override
void close();
diff --git a/opendj3-server-dev/src/server/org/opends/server/types/BackupConfig.java b/opendj3-server-dev/src/server/org/opends/server/types/BackupConfig.java
index 14daba3..533c659 100644
--- a/opendj3-server-dev/src/server/org/opends/server/types/BackupConfig.java
+++ b/opendj3-server-dev/src/server/org/opends/server/types/BackupConfig.java
@@ -22,9 +22,11 @@
*
*
* Copyright 2006-2008 Sun Microsystems, Inc.
+ * Portions Copyright 2015 Forgerock AS
*/
package org.opends.server.types;
+import java.io.FilenameFilter;
/**
* This class defines a data structure for holding configuration
@@ -50,36 +52,51 @@
mayInvoke=true)
public final class BackupConfig extends OperationConfig
{
- // The path to the directory in which the backup file(s) should be
- // created.
+ /**
+ * The path to the directory in which the backup file(s) should be
+ * created.
+ */
private BackupDirectory backupDirectory;
- // Indicates whether the data should be compressed as it is written.
+ /** Indicates whether the data should be compressed as it is written. */
private boolean compressData;
- // Indicates whether the data should be encrypted as it is written.
+ /** Indicates whether the data should be encrypted as it is written. */
private boolean encryptData;
- // Indicates whether to generate a cryptographic hash of the data as
- // it is written.
+ /**
+ * Indicates whether to generate a cryptographic hash of the data as
+ * it is written.
+ */
private boolean hashData;
- // Indicates whether to attempt an incremental backup.
+ /** Indicates whether to attempt an incremental backup. */
private boolean isIncremental;
- // Indicates whether to digitally sign the hash when the backup is
- // complete.
+ /**
+ * Indicates whether to digitally sign the hash when the backup is
+ * complete.
+ */
private boolean signHash;
- // The unique identifier assigned to this backup operation (which
- // may be used to indicate which version to restore if multiple
- // backups are in the same directory).
+ /**
+ * The unique identifier assigned to this backup operation (which
+ * may be used to indicate which version to restore if multiple
+ * backups are in the same directory).
+ */
private String backupID;
- // The unique ID for the existing full or incremental backup against
- // which the incremental backup should be based.
+ /**
+ * The unique ID for the existing full or incremental backup against
+ * which the incremental backup should be based.
+ */
private String incrementalBaseID;
+ /**
+ * The filename filter to decide which files should be included as defined
+ * by the storage.
+ */
+ private FilenameFilter filesToBackupFilter;
/**
@@ -298,5 +315,25 @@
{
this.signHash = signHash;
}
+
+ /**
+ * Returns the storage-defined filename filter deciding which files should go into a backup.
+ *
+ * @return the storage-defined filename filter deciding which files should go into a backup
+ */
+ public FilenameFilter getFilesToBackupFilter()
+ {
+ return filesToBackupFilter;
+ }
+
+ /**
+ * Sets the storage-defined filter for files belonging to the backend.
+ *
+ * @param filenameFilter the filenameFilter to set
+ */
+ public void setFilesToBackupFilter(FilenameFilter filenameFilter)
+ {
+ this.filesToBackupFilter = filenameFilter;
+ }
}
--
Gitblit v1.10.0