Time to Live (TTL) is a mechanism that allows you to automatically expire database records. TTL is expressed as the amount of time data is allowed to live in the database. Data which has reached its expiration timeout value can no longer be retrieved, and will not appear in any database statistics. Whether the data is physically removed from the database is determined by an internal mechanism that is not user-controllable.
TTL represents a minimum guaranteed time to live. Data expires on hour or day boundaries. This means that with a one hour TTL, there can be as much as two hours worth of unexpired data. For example (using a time format of hour:minute:second), given a one hour TTL, data written between 00:00:00.000 and 00:59:59.999 will expire at 02:00:00.000 because the data is guaranteed to expire no less than one hour from when it is written.
Expired data is invisible to queries and database statistics, but even so it is using disk space until it has been purged. The expired data is purged from disk at some point in time after its expiration date. The exact time when the data is purged is driven by internal mechanisms and the workload on your database.
The TTL value for a database record can be updated at any time before the expiration value has been reached. Data that has expired can no longer be modified, and this includes its TTL value.
TTL is more efficient than manual user-deletion of the record because it avoids the overhead of writing a database log entry for the data deletion. The deletion also does not appear in the replication stream.
The following provides a brief introduction to using Time to Live. For a more complete description of this mechanism, see the com.sleepycat.je.WriteOptions javadoc.
TTL values are specified on a record by record basis using
the WriteOptions
class, which can
but used by various put()
methods
when writing to the database. For example, variations of
Database.put()
,
PrimaryIndex.put()
, and
Cursor.put()
exist that accept a
WriteOptions
class instance.
WriteOptions
allows
you to identify the number of days or hours the record will exist
in the database before expiring. A duration interval specified in
days is recommended because this results in the least amount of
storage consumed in the store. However, if you want a TTL value
that is not an even multiple of days, then specify the TTL
value in hours.
The code example from Writing Records to the Database can be extended to specify a TTL value of 5 days like this:
package je.gettingStarted; import com.sleepycat.je.Database; import com.sleepycat.je.DatabaseEntry;import com.sleepycat.je.Put; import com.sleepycat.je.WriteOptions;
... // Environment and database opens omitted for clarity. // Environment and database must NOT be opened read-only. String aKey = "myFirstKey"; String aData = "myFirstData"; try { DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8")); DatabaseEntry theData = new DatabaseEntry(aData.getBytes("UTF-8"));WriteOptions wo = new WriteOptions(); // This sets the TTL using day units. Another variation // of setTTL() exists that accepts a TimeUnit class instance. wo.setTTL(5); myDatabase.put(null, // Transaction handle. theKey, // Record's key. theData, // Record's data. Put.NO_OVERWRITE, // If the record exists, // do not overwrite it. wo); // WriteOptions instance.
} catch (Exception e) { // Exception handling goes here }
To update the expiration time for a record, you update the record as normal, and at the same time specify the new expiration time. However, you must also indicate that the expiration time is to be updated. By default, you can modify the record and the expiration time will not be modified, even if you specify a new TTL value for the record.
To indicate that the the expiration time is to be updated,
specify true
to the
WriteOptions.setUpdateTTL()
method. For example, using the previous example, to change
the TTL value to 10 days, do the following:
package je.gettingStarted; import com.sleepycat.je.Database; import com.sleepycat.je.DatabaseEntry; import com.sleepycat.je.Put; import com.sleepycat.je.WriteOptions; ... // Environment and database opens omitted for clarity. // Environment and database must NOT be opened read-only. String aKey = "myFirstKey"; String aData = "myFirstData"; try { DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8")); DatabaseEntry theData = new DatabaseEntry(aData.getBytes("UTF-8")); WriteOptions wo = new WriteOptions(); // This sets the TTL using day units. Another variation // of setTTL() exists that accepts a TimeUnit class instance. wo.setTTL(5);// If the record currently exists, update the TTL value wo.setUpdateTTL(true);
myDatabase.put(null, // Transaction handle. theKey, // Record's key. theData, // Record's data.Put.OVERWRITE, // If the record exists, // overwrite it.
wo); // WriteOptions instance. } catch (Exception e) { // Exception handling goes here }
If you have set a TTL value for a record and you later decide you
do not want it to ever automatically expire, you can turn off
TTL by setting a TTL value of 0
:
package je.gettingStarted;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.Put;
import com.sleepycat.je.WriteOptions;
...
// Environment and database opens omitted for clarity.
// Environment and database must NOT be opened read-only.
String aKey = "myFirstKey";
String aData = "myFirstData";
try {
DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
DatabaseEntry theData = new DatabaseEntry(aData.getBytes("UTF-8"));
WriteOptions wo = new WriteOptions();
// Turn off automatic expiration of this record.
wo.setTTL(0);
wo.setUpdateTTL(true);
myDatabase.put(null, // Transaction handle.
theKey, // Record's key.
theData, // Record's data.
Put.OVERWRITE, // If the record exists,
// overwrite it.
wo); // WriteOptions instance.
} catch (Exception e) {
// Exception handling goes here
}