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 
6 package org.rocksdb;
7 
8 import java.io.File;
9 
10 /**
11  * <p>BackupableDBOptions to control the behavior of a backupable database.
12  * It will be used during the creation of a {@link org.rocksdb.BackupEngine}.
13  * </p>
14  * <p>Note that dispose() must be called before an Options instance
15  * become out-of-scope to release the allocated memory in c++.</p>
16  *
17  * @see org.rocksdb.BackupEngine
18  */
19 public class BackupableDBOptions extends RocksObject {
20 
21   private Env backupEnv = null;
22   private Logger infoLog = null;
23   private RateLimiter backupRateLimiter = null;
24   private RateLimiter restoreRateLimiter = null;
25 
26   /**
27    * <p>BackupableDBOptions constructor.</p>
28    *
29    * @param path Where to keep the backup files. Has to be different than db
30    *   name. Best to set this to {@code db name_ + "/backups"}
31    * @throws java.lang.IllegalArgumentException if illegal path is used.
32    */
BackupableDBOptions(final String path)33   public BackupableDBOptions(final String path) {
34     super(newBackupableDBOptions(ensureWritableFile(path)));
35   }
36 
ensureWritableFile(final String path)37   private static String ensureWritableFile(final String path) {
38     final File backupPath = path == null ? null : new File(path);
39     if (backupPath == null || !backupPath.isDirectory() ||
40         !backupPath.canWrite()) {
41       throw new IllegalArgumentException("Illegal path provided.");
42     } else {
43       return path;
44     }
45   }
46 
47   /**
48    * <p>Returns the path to the BackupableDB directory.</p>
49    *
50    * @return the path to the BackupableDB directory.
51    */
backupDir()52   public String backupDir() {
53     assert(isOwningHandle());
54     return backupDir(nativeHandle_);
55   }
56 
57   /**
58    * Backup Env object. It will be used for backup file I/O. If it's
59    * null, backups will be written out using DBs Env. Otherwise
60    * backup's I/O will be performed using this object.
61    *
62    * If you want to have backups on HDFS, use HDFS Env here!
63    *
64    * Default: null
65    *
66    * @param env The environment to use
67    * @return instance of current BackupableDBOptions.
68    */
setBackupEnv(final Env env)69   public BackupableDBOptions setBackupEnv(final Env env) {
70     assert(isOwningHandle());
71     setBackupEnv(nativeHandle_, env.nativeHandle_);
72     this.backupEnv = env;
73     return this;
74   }
75 
76   /**
77    * Backup Env object. It will be used for backup file I/O. If it's
78    * null, backups will be written out using DBs Env. Otherwise
79    * backup's I/O will be performed using this object.
80    *
81    * If you want to have backups on HDFS, use HDFS Env here!
82    *
83    * Default: null
84    *
85    * @return The environment in use
86    */
backupEnv()87   public Env backupEnv() {
88     return this.backupEnv;
89   }
90 
91   /**
92    * <p>Share table files between backups.</p>
93    *
94    * @param shareTableFiles If {@code share_table_files == true}, backup will
95    *   assume that table files with same name have the same contents. This
96    *   enables incremental backups and avoids unnecessary data copies. If
97    *   {@code share_table_files == false}, each backup will be on its own and
98    *   will not share any data with other backups.
99    *
100    * <p>Default: true</p>
101    *
102    * @return instance of current BackupableDBOptions.
103    */
setShareTableFiles(final boolean shareTableFiles)104   public BackupableDBOptions setShareTableFiles(final boolean shareTableFiles) {
105     assert(isOwningHandle());
106     setShareTableFiles(nativeHandle_, shareTableFiles);
107     return this;
108   }
109 
110   /**
111    * <p>Share table files between backups.</p>
112    *
113    * @return boolean value indicating if SST files will be shared between
114    *     backups.
115    */
shareTableFiles()116   public boolean shareTableFiles() {
117     assert(isOwningHandle());
118     return shareTableFiles(nativeHandle_);
119   }
120 
121   /**
122    * Set the logger to use for Backup info and error messages
123    *
124    * @param logger The logger to use for the backup
125    * @return instance of current BackupableDBOptions.
126    */
setInfoLog(final Logger logger)127   public BackupableDBOptions setInfoLog(final Logger logger) {
128     assert(isOwningHandle());
129     setInfoLog(nativeHandle_, logger.nativeHandle_);
130     this.infoLog = logger;
131     return this;
132   }
133 
134   /**
135    * Set the logger to use for Backup info and error messages
136    *
137    * Default: null
138    *
139    * @return The logger in use for the backup
140    */
infoLog()141   public Logger infoLog() {
142     return this.infoLog;
143   }
144 
145   /**
146    * <p>Set synchronous backups.</p>
147    *
148    * @param sync If {@code sync == true}, we can guarantee you'll get consistent
149    *   backup even on a machine crash/reboot. Backup process is slower with sync
150    *   enabled. If {@code sync == false}, we don't guarantee anything on machine
151    *   reboot. However, chances are some of the backups are consistent.
152    *
153    * <p>Default: true</p>
154    *
155    * @return instance of current BackupableDBOptions.
156    */
setSync(final boolean sync)157   public BackupableDBOptions setSync(final boolean sync) {
158     assert(isOwningHandle());
159     setSync(nativeHandle_, sync);
160     return this;
161   }
162 
163   /**
164    * <p>Are synchronous backups activated.</p>
165    *
166    * @return boolean value if synchronous backups are configured.
167    */
sync()168   public boolean sync() {
169     assert(isOwningHandle());
170     return sync(nativeHandle_);
171   }
172 
173   /**
174    * <p>Set if old data will be destroyed.</p>
175    *
176    * @param destroyOldData If true, it will delete whatever backups there are
177    *   already.
178    *
179    * <p>Default: false</p>
180    *
181    * @return instance of current BackupableDBOptions.
182    */
setDestroyOldData(final boolean destroyOldData)183   public BackupableDBOptions setDestroyOldData(final boolean destroyOldData) {
184     assert(isOwningHandle());
185     setDestroyOldData(nativeHandle_, destroyOldData);
186     return this;
187   }
188 
189   /**
190    * <p>Returns if old data will be destroyed will performing new backups.</p>
191    *
192    * @return boolean value indicating if old data will be destroyed.
193    */
destroyOldData()194   public boolean destroyOldData() {
195     assert(isOwningHandle());
196     return destroyOldData(nativeHandle_);
197   }
198 
199   /**
200    * <p>Set if log files shall be persisted.</p>
201    *
202    * @param backupLogFiles If false, we won't backup log files. This option can
203    *   be useful for backing up in-memory databases where log file are
204    *   persisted, but table files are in memory.
205    *
206    * <p>Default: true</p>
207    *
208    * @return instance of current BackupableDBOptions.
209    */
setBackupLogFiles(final boolean backupLogFiles)210   public BackupableDBOptions setBackupLogFiles(final boolean backupLogFiles) {
211     assert(isOwningHandle());
212     setBackupLogFiles(nativeHandle_, backupLogFiles);
213     return this;
214   }
215 
216   /**
217    * <p>Return information if log files shall be persisted.</p>
218    *
219    * @return boolean value indicating if log files will be persisted.
220    */
backupLogFiles()221   public boolean backupLogFiles() {
222     assert(isOwningHandle());
223     return backupLogFiles(nativeHandle_);
224   }
225 
226   /**
227    * <p>Set backup rate limit.</p>
228    *
229    * @param backupRateLimit Max bytes that can be transferred in a second during
230    *   backup. If 0 or negative, then go as fast as you can.
231    *
232    * <p>Default: 0</p>
233    *
234    * @return instance of current BackupableDBOptions.
235    */
setBackupRateLimit(long backupRateLimit)236   public BackupableDBOptions setBackupRateLimit(long backupRateLimit) {
237     assert(isOwningHandle());
238     backupRateLimit = (backupRateLimit <= 0) ? 0 : backupRateLimit;
239     setBackupRateLimit(nativeHandle_, backupRateLimit);
240     return this;
241   }
242 
243   /**
244    * <p>Return backup rate limit which described the max bytes that can be
245    * transferred in a second during backup.</p>
246    *
247    * @return numerical value describing the backup transfer limit in bytes per
248    *   second.
249    */
backupRateLimit()250   public long backupRateLimit() {
251     assert(isOwningHandle());
252     return backupRateLimit(nativeHandle_);
253   }
254 
255   /**
256    * Backup rate limiter. Used to control transfer speed for backup. If this is
257    * not null, {@link #backupRateLimit()} is ignored.
258    *
259    * Default: null
260    *
261    * @param backupRateLimiter The rate limiter to use for the backup
262    * @return instance of current BackupableDBOptions.
263    */
setBackupRateLimiter(final RateLimiter backupRateLimiter)264   public BackupableDBOptions setBackupRateLimiter(final RateLimiter backupRateLimiter) {
265     assert(isOwningHandle());
266     setBackupRateLimiter(nativeHandle_, backupRateLimiter.nativeHandle_);
267     this.backupRateLimiter = backupRateLimiter;
268     return this;
269   }
270 
271   /**
272    * Backup rate limiter. Used to control transfer speed for backup. If this is
273    * not null, {@link #backupRateLimit()} is ignored.
274    *
275    * Default: null
276    *
277    * @return The rate limiter in use for the backup
278    */
backupRateLimiter()279   public RateLimiter backupRateLimiter() {
280     assert(isOwningHandle());
281     return this.backupRateLimiter;
282   }
283 
284   /**
285    * <p>Set restore rate limit.</p>
286    *
287    * @param restoreRateLimit Max bytes that can be transferred in a second
288    *   during restore. If 0 or negative, then go as fast as you can.
289    *
290    * <p>Default: 0</p>
291    *
292    * @return instance of current BackupableDBOptions.
293    */
setRestoreRateLimit(long restoreRateLimit)294   public BackupableDBOptions setRestoreRateLimit(long restoreRateLimit) {
295     assert(isOwningHandle());
296     restoreRateLimit = (restoreRateLimit <= 0) ? 0 : restoreRateLimit;
297     setRestoreRateLimit(nativeHandle_, restoreRateLimit);
298     return this;
299   }
300 
301   /**
302    * <p>Return restore rate limit which described the max bytes that can be
303    * transferred in a second during restore.</p>
304    *
305    * @return numerical value describing the restore transfer limit in bytes per
306    *   second.
307    */
restoreRateLimit()308   public long restoreRateLimit() {
309     assert(isOwningHandle());
310     return restoreRateLimit(nativeHandle_);
311   }
312 
313   /**
314    * Restore rate limiter. Used to control transfer speed during restore. If
315    * this is not null, {@link #restoreRateLimit()} is ignored.
316    *
317    * Default: null
318    *
319    * @param restoreRateLimiter The rate limiter to use during restore
320    * @return instance of current BackupableDBOptions.
321    */
setRestoreRateLimiter(final RateLimiter restoreRateLimiter)322   public BackupableDBOptions setRestoreRateLimiter(final RateLimiter restoreRateLimiter) {
323     assert(isOwningHandle());
324     setRestoreRateLimiter(nativeHandle_, restoreRateLimiter.nativeHandle_);
325     this.restoreRateLimiter = restoreRateLimiter;
326     return this;
327   }
328 
329   /**
330    * Restore rate limiter. Used to control transfer speed during restore. If
331    * this is not null, {@link #restoreRateLimit()} is ignored.
332    *
333    * Default: null
334    *
335    * @return The rate limiter in use during restore
336    */
restoreRateLimiter()337   public RateLimiter restoreRateLimiter() {
338     assert(isOwningHandle());
339     return this.restoreRateLimiter;
340   }
341 
342   /**
343    * <p>Only used if share_table_files is set to true. If true, will consider
344    * that backups can come from different databases, hence a sst is not uniquely
345    * identified by its name, but by the triple (file name, crc32, file length)
346    * </p>
347    *
348    * @param shareFilesWithChecksum boolean value indicating if SST files are
349    *   stored using the triple (file name, crc32, file length) and not its name.
350    *
351    * <p>Note: this is an experimental option, and you'll need to set it manually
352    * turn it on only if you know what you're doing*</p>
353    *
354    * <p>Default: false</p>
355    *
356    * @return instance of current BackupableDBOptions.
357    */
setShareFilesWithChecksum( final boolean shareFilesWithChecksum)358   public BackupableDBOptions setShareFilesWithChecksum(
359       final boolean shareFilesWithChecksum) {
360     assert(isOwningHandle());
361     setShareFilesWithChecksum(nativeHandle_, shareFilesWithChecksum);
362     return this;
363   }
364 
365   /**
366    * <p>Return of share files with checksum is active.</p>
367    *
368    * @return boolean value indicating if share files with checksum
369    *     is active.
370    */
shareFilesWithChecksum()371   public boolean shareFilesWithChecksum() {
372     assert(isOwningHandle());
373     return shareFilesWithChecksum(nativeHandle_);
374   }
375 
376   /**
377    * Up to this many background threads will copy files for
378    * {@link BackupEngine#createNewBackup(RocksDB, boolean)} and
379    * {@link BackupEngine#restoreDbFromBackup(int, String, String, RestoreOptions)}
380    *
381    * Default: 1
382    *
383    * @param maxBackgroundOperations The maximum number of background threads
384    * @return instance of current BackupableDBOptions.
385    */
setMaxBackgroundOperations( final int maxBackgroundOperations)386   public BackupableDBOptions setMaxBackgroundOperations(
387       final int maxBackgroundOperations) {
388     assert(isOwningHandle());
389     setMaxBackgroundOperations(nativeHandle_, maxBackgroundOperations);
390     return this;
391   }
392 
393   /**
394    * Up to this many background threads will copy files for
395    * {@link BackupEngine#createNewBackup(RocksDB, boolean)} and
396    * {@link BackupEngine#restoreDbFromBackup(int, String, String, RestoreOptions)}
397    *
398    * Default: 1
399    *
400    * @return The maximum number of background threads
401    */
maxBackgroundOperations()402   public int maxBackgroundOperations() {
403     assert(isOwningHandle());
404     return maxBackgroundOperations(nativeHandle_);
405   }
406 
407   /**
408    * During backup user can get callback every time next
409    * {@link #callbackTriggerIntervalSize()} bytes being copied.
410    *
411    * Default: 4194304
412    *
413    * @param callbackTriggerIntervalSize The interval size for the
414    *     callback trigger
415    * @return instance of current BackupableDBOptions.
416    */
setCallbackTriggerIntervalSize( final long callbackTriggerIntervalSize)417   public BackupableDBOptions setCallbackTriggerIntervalSize(
418       final long callbackTriggerIntervalSize) {
419     assert(isOwningHandle());
420     setCallbackTriggerIntervalSize(nativeHandle_, callbackTriggerIntervalSize);
421     return this;
422   }
423 
424   /**
425    * During backup user can get callback every time next
426    * {@link #callbackTriggerIntervalSize()} bytes being copied.
427    *
428    * Default: 4194304
429    *
430    * @return The interval size for the callback trigger
431    */
callbackTriggerIntervalSize()432   public long callbackTriggerIntervalSize() {
433     assert(isOwningHandle());
434     return callbackTriggerIntervalSize(nativeHandle_);
435   }
436 
newBackupableDBOptions(final String path)437   private native static long newBackupableDBOptions(final String path);
backupDir(long handle)438   private native String backupDir(long handle);
setBackupEnv(final long handle, final long envHandle)439   private native void setBackupEnv(final long handle, final long envHandle);
setShareTableFiles(long handle, boolean flag)440   private native void setShareTableFiles(long handle, boolean flag);
shareTableFiles(long handle)441   private native boolean shareTableFiles(long handle);
setInfoLog(final long handle, final long infoLogHandle)442   private native void setInfoLog(final long handle, final long infoLogHandle);
setSync(long handle, boolean flag)443   private native void setSync(long handle, boolean flag);
sync(long handle)444   private native boolean sync(long handle);
setDestroyOldData(long handle, boolean flag)445   private native void setDestroyOldData(long handle, boolean flag);
destroyOldData(long handle)446   private native boolean destroyOldData(long handle);
setBackupLogFiles(long handle, boolean flag)447   private native void setBackupLogFiles(long handle, boolean flag);
backupLogFiles(long handle)448   private native boolean backupLogFiles(long handle);
setBackupRateLimit(long handle, long rateLimit)449   private native void setBackupRateLimit(long handle, long rateLimit);
backupRateLimit(long handle)450   private native long backupRateLimit(long handle);
setBackupRateLimiter(long handle, long rateLimiterHandle)451   private native void setBackupRateLimiter(long handle, long rateLimiterHandle);
setRestoreRateLimit(long handle, long rateLimit)452   private native void setRestoreRateLimit(long handle, long rateLimit);
restoreRateLimit(long handle)453   private native long restoreRateLimit(long handle);
setRestoreRateLimiter(final long handle, final long rateLimiterHandle)454   private native void setRestoreRateLimiter(final long handle,
455       final long rateLimiterHandle);
setShareFilesWithChecksum(long handle, boolean flag)456   private native void setShareFilesWithChecksum(long handle, boolean flag);
shareFilesWithChecksum(long handle)457   private native boolean shareFilesWithChecksum(long handle);
setMaxBackgroundOperations(final long handle, final int maxBackgroundOperations)458   private native void setMaxBackgroundOperations(final long handle,
459       final int maxBackgroundOperations);
maxBackgroundOperations(final long handle)460   private native int maxBackgroundOperations(final long handle);
setCallbackTriggerIntervalSize(final long handle, long callbackTriggerIntervalSize)461   private native void setCallbackTriggerIntervalSize(final long handle,
462       long callbackTriggerIntervalSize);
callbackTriggerIntervalSize(final long handle)463   private native long callbackTriggerIntervalSize(final long handle);
disposeInternal(final long handle)464   @Override protected final native void disposeInternal(final long handle);
465 }
466