1 // Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 package org.rocksdb;
6 
7 import java.util.List;
8 
9 /**
10  * BackupEngine allows you to backup
11  * and restore the database
12  *
13  * Be aware, that `new BackupEngine` takes time proportional to the amount
14  * of backups. So if you have a slow filesystem to backup (like HDFS)
15  * and you have a lot of backups then restoring can take some time.
16  * That's why we recommend to limit the number of backups.
17  * Also we recommend to keep BackupEngine alive and not to recreate it every
18  * time you need to do a backup.
19  */
20 public class BackupEngine extends RocksObject implements AutoCloseable {
21 
BackupEngine(final long nativeHandle)22   protected BackupEngine(final long nativeHandle) {
23     super(nativeHandle);
24   }
25 
26   /**
27    * Opens a new Backup Engine
28    *
29    * @param env The environment that the backup engine should operate within
30    * @param options Any options for the backup engine
31    *
32    * @return A new BackupEngine instance
33    * @throws RocksDBException thrown if the backup engine could not be opened
34    */
open(final Env env, final BackupableDBOptions options)35   public static BackupEngine open(final Env env,
36       final BackupableDBOptions options) throws RocksDBException {
37     return new BackupEngine(open(env.nativeHandle_, options.nativeHandle_));
38   }
39 
40   /**
41    * Captures the state of the database in the latest backup
42    *
43    * Just a convenience for {@link #createNewBackup(RocksDB, boolean)} with
44    * the flushBeforeBackup parameter set to false
45    *
46    * @param db The database to backup
47    *
48    * Note - This method is not thread safe
49    *
50    * @throws RocksDBException thrown if a new backup could not be created
51    */
createNewBackup(final RocksDB db)52   public void createNewBackup(final RocksDB db) throws RocksDBException {
53     createNewBackup(db, false);
54   }
55 
56   /**
57    * Captures the state of the database in the latest backup
58    *
59    * @param db The database to backup
60    * @param flushBeforeBackup When true, the Backup Engine will first issue a
61    *                          memtable flush and only then copy the DB files to
62    *                          the backup directory. Doing so will prevent log
63    *                          files from being copied to the backup directory
64    *                          (since flush will delete them).
65    *                          When false, the Backup Engine will not issue a
66    *                          flush before starting the backup. In that case,
67    *                          the backup will also include log files
68    *                          corresponding to live memtables. If writes have
69    *                          been performed with the write ahead log disabled,
70    *                          set flushBeforeBackup to true to prevent those
71    *                          writes from being lost. Otherwise, the backup will
72    *                          always be consistent with the current state of the
73    *                          database regardless of the flushBeforeBackup
74    *                          parameter.
75    *
76    * Note - This method is not thread safe
77    *
78    * @throws RocksDBException thrown if a new backup could not be created
79    */
createNewBackup( final RocksDB db, final boolean flushBeforeBackup)80   public void createNewBackup(
81       final RocksDB db, final boolean flushBeforeBackup)
82       throws RocksDBException {
83     assert (isOwningHandle());
84     createNewBackup(nativeHandle_, db.nativeHandle_, flushBeforeBackup);
85   }
86 
87   /**
88    * Captures the state of the database in the latest backup along with
89    * application specific metadata.
90    *
91    * @param db The database to backup
92    * @param metadata Application metadata
93    * @param flushBeforeBackup When true, the Backup Engine will first issue a
94    *                          memtable flush and only then copy the DB files to
95    *                          the backup directory. Doing so will prevent log
96    *                          files from being copied to the backup directory
97    *                          (since flush will delete them).
98    *                          When false, the Backup Engine will not issue a
99    *                          flush before starting the backup. In that case,
100    *                          the backup will also include log files
101    *                          corresponding to live memtables. If writes have
102    *                          been performed with the write ahead log disabled,
103    *                          set flushBeforeBackup to true to prevent those
104    *                          writes from being lost. Otherwise, the backup will
105    *                          always be consistent with the current state of the
106    *                          database regardless of the flushBeforeBackup
107    *                          parameter.
108    *
109    * Note - This method is not thread safe
110    *
111    * @throws RocksDBException thrown if a new backup could not be created
112    */
createNewBackupWithMetadata(final RocksDB db, final String metadata, final boolean flushBeforeBackup)113   public void createNewBackupWithMetadata(final RocksDB db, final String metadata,
114       final boolean flushBeforeBackup) throws RocksDBException {
115     assert (isOwningHandle());
116     createNewBackupWithMetadata(nativeHandle_, db.nativeHandle_, metadata, flushBeforeBackup);
117   }
118 
119   /**
120    * Gets information about the available
121    * backups
122    *
123    * @return A list of information about each available backup
124    */
getBackupInfo()125   public List<BackupInfo> getBackupInfo() {
126     assert (isOwningHandle());
127     return getBackupInfo(nativeHandle_);
128   }
129 
130   /**
131    * <p>Returns a list of corrupted backup ids. If there
132    * is no corrupted backup the method will return an
133    * empty list.</p>
134    *
135    * @return array of backup ids as int ids.
136    */
getCorruptedBackups()137   public int[] getCorruptedBackups() {
138     assert(isOwningHandle());
139     return getCorruptedBackups(nativeHandle_);
140   }
141 
142   /**
143    * <p>Will delete all the files we don't need anymore. It will
144    * do the full scan of the files/ directory and delete all the
145    * files that are not referenced.</p>
146    *
147    * @throws RocksDBException thrown if error happens in underlying
148    *    native library.
149    */
garbageCollect()150   public void garbageCollect() throws RocksDBException {
151     assert(isOwningHandle());
152     garbageCollect(nativeHandle_);
153   }
154 
155   /**
156    * Deletes old backups, keeping just the latest numBackupsToKeep
157    *
158    * @param numBackupsToKeep The latest n backups to keep
159    *
160    * @throws RocksDBException thrown if the old backups could not be deleted
161    */
purgeOldBackups( final int numBackupsToKeep)162   public void purgeOldBackups(
163       final int numBackupsToKeep) throws RocksDBException {
164     assert (isOwningHandle());
165     purgeOldBackups(nativeHandle_, numBackupsToKeep);
166   }
167 
168   /**
169    * Deletes a backup
170    *
171    * @param backupId The id of the backup to delete
172    *
173    * @throws RocksDBException thrown if the backup could not be deleted
174    */
deleteBackup(final int backupId)175   public void deleteBackup(final int backupId) throws RocksDBException {
176     assert (isOwningHandle());
177     deleteBackup(nativeHandle_, backupId);
178   }
179 
180   /**
181    * Restore the database from a backup
182    *
183    * IMPORTANT: if options.share_table_files == true and you restore the DB
184    * from some backup that is not the latest, and you start creating new
185    * backups from the new DB, they will probably fail!
186    *
187    * Example: Let's say you have backups 1, 2, 3, 4, 5 and you restore 3.
188    * If you add new data to the DB and try creating a new backup now, the
189    * database will diverge from backups 4 and 5 and the new backup will fail.
190    * If you want to create new backup, you will first have to delete backups 4
191    * and 5.
192    *
193    * @param backupId The id of the backup to restore
194    * @param dbDir The directory to restore the backup to, i.e. where your
195    *              database is
196    * @param walDir The location of the log files for your database,
197    *               often the same as dbDir
198    * @param restoreOptions Options for controlling the restore
199    *
200    * @throws RocksDBException thrown if the database could not be restored
201    */
restoreDbFromBackup( final int backupId, final String dbDir, final String walDir, final RestoreOptions restoreOptions)202   public void restoreDbFromBackup(
203       final int backupId, final String dbDir, final String walDir,
204       final RestoreOptions restoreOptions) throws RocksDBException {
205     assert (isOwningHandle());
206     restoreDbFromBackup(nativeHandle_, backupId, dbDir, walDir,
207         restoreOptions.nativeHandle_);
208   }
209 
210   /**
211    * Restore the database from the latest backup
212    *
213    * @param dbDir The directory to restore the backup to, i.e. where your
214    *              database is
215    * @param walDir The location of the log files for your database, often the
216    *               same as dbDir
217    * @param restoreOptions Options for controlling the restore
218    *
219    * @throws RocksDBException thrown if the database could not be restored
220    */
restoreDbFromLatestBackup( final String dbDir, final String walDir, final RestoreOptions restoreOptions)221   public void restoreDbFromLatestBackup(
222       final String dbDir, final String walDir,
223       final RestoreOptions restoreOptions) throws RocksDBException {
224     assert (isOwningHandle());
225     restoreDbFromLatestBackup(nativeHandle_, dbDir, walDir,
226         restoreOptions.nativeHandle_);
227   }
228 
open(final long env, final long backupableDbOptions)229   private native static long open(final long env,
230       final long backupableDbOptions) throws RocksDBException;
231 
createNewBackup(final long handle, final long dbHandle, final boolean flushBeforeBackup)232   private native void createNewBackup(final long handle, final long dbHandle,
233       final boolean flushBeforeBackup) throws RocksDBException;
234 
createNewBackupWithMetadata(final long handle, final long dbHandle, final String metadata, final boolean flushBeforeBackup)235   private native void createNewBackupWithMetadata(final long handle, final long dbHandle,
236       final String metadata, final boolean flushBeforeBackup) throws RocksDBException;
237 
getBackupInfo(final long handle)238   private native List<BackupInfo> getBackupInfo(final long handle);
239 
getCorruptedBackups(final long handle)240   private native int[] getCorruptedBackups(final long handle);
241 
garbageCollect(final long handle)242   private native void garbageCollect(final long handle) throws RocksDBException;
243 
purgeOldBackups(final long handle, final int numBackupsToKeep)244   private native void purgeOldBackups(final long handle,
245       final int numBackupsToKeep) throws RocksDBException;
246 
deleteBackup(final long handle, final int backupId)247   private native void deleteBackup(final long handle, final int backupId)
248       throws RocksDBException;
249 
restoreDbFromBackup(final long handle, final int backupId, final String dbDir, final String walDir, final long restoreOptionsHandle)250   private native void restoreDbFromBackup(final long handle, final int backupId,
251       final String dbDir, final String walDir, final long restoreOptionsHandle)
252       throws RocksDBException;
253 
restoreDbFromLatestBackup(final long handle, final String dbDir, final String walDir, final long restoreOptionsHandle)254   private native void restoreDbFromLatestBackup(final long handle,
255       final String dbDir, final String walDir, final long restoreOptionsHandle)
256       throws RocksDBException;
257 
disposeInternal(final long handle)258   @Override protected final native void disposeInternal(final long handle);
259 }
260