mirror of
https://github.com/scylladb/scylladb.git
synced 2026-05-22 15:52:13 +00:00
Add to the SELECT documentation (docs/cql/dml/select.rst) documentation of the new ability to select WRITETIME() and TTL() of a single element of map, set or UDT. Also in the TTL documentation (docs/cql/time-to-live.rst), which already had a section on "TTL for a collection", add a mention of the ability to read a single element's TTL(), and an example. Signed-off-by: Nadav Har'El <nyh@scylladb.com>
149 lines
6.4 KiB
ReStructuredText
149 lines
6.4 KiB
ReStructuredText
|
||
|
||
.. highlight:: cql
|
||
|
||
.. _time-to-live:
|
||
|
||
Expiring Data with Time to Live (TTL)
|
||
-------------------------------------
|
||
|
||
ScyllaDB (as well as Apache Cassandra) provides the functionality to automatically delete expired data according to the Time to Live (or TTL) value.
|
||
TTL is measured in seconds. If the field is not updated within the TTL it is deleted.
|
||
The TTL can be set when defining a Table (CREATE), or when using the INSERT and UPDATE queries.
|
||
The expiration works at the individual column level, which provides a lot of flexibility.
|
||
By default, the TTL value is null, which means that the data will not expire.
|
||
|
||
This document is about CQL's classic per-write TTL feature, where individual
|
||
columns from the same row can expire at separate times if written at
|
||
different times. ScyllaDB also supports an alternative TTL feature,
|
||
`Per-row TTL <https://docs.scylladb.com/stable/cql/cql-extensions.html#per-row-ttl>`_.
|
||
In *per-row TTL* each row has an expiration time for the entire row,
|
||
defined by the value of the expiration-time column. In per-row TTL, the
|
||
entire row expires together regardless of how its indivial columns were
|
||
written, and the expiration time of an entire row can be modified by modifying
|
||
the expiration-time column. Another benefit of per-row TTL is that it
|
||
generates a CDC event when a row expires - in contrast in per-write TTL
|
||
(the feature described in this document) where expiration events do not
|
||
show up in CDC.
|
||
|
||
.. note::
|
||
|
||
The expiration time is always calculated as *now() on the Coordinator + TTL* where, *now()* is the wall clock during the corresponding write operation.
|
||
In particular, it means that a value given via USING TIMESTAMP is **not** taken into an account for an expiration calculation.
|
||
|
||
TTL using UPDATE and INSERT
|
||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||
|
||
To set the TTL value using the UPDATE query use the following command:
|
||
|
||
.. code-block:: cql
|
||
|
||
UPDATE heartrate USING TTL 600 SET heart_rate =
|
||
110 WHERE pet_chip_id = 123e4567-e89b-12d3-a456-426655440b23;
|
||
|
||
In this case, the TTL for the heart_rate column is set 10 minutes (600 seconds).
|
||
|
||
To check the TTL, use the ``TTL()`` function:
|
||
|
||
.. code-block:: cql
|
||
|
||
SELECT name, heart_rate, TTL(heart_rate)
|
||
FROM heartrate WHERE pet_chip_id = 123e4567-e89b-12d3-a456-426655440b23;
|
||
|
||
The TTL has a value that is lower than 600 as a few seconds passed between setting the TTL and the SELECT query.
|
||
If you wait 10 minutes and run this command again, you will get a null value for the heart_rate.
|
||
|
||
It’s also possible to set the TTL when performing an INSERT. To do this use:
|
||
|
||
.. code-block:: cql
|
||
|
||
INSERT INTO heartrate(pet_chip_id, name, heart_rate) VALUES (c63e71f0-936e-11ea-bb37-0242ac130002, 'Rocky', 87) USING TTL 30;
|
||
|
||
In this case, a TTL of 30 seconds is set.
|
||
|
||
|
||
TTL for a Table
|
||
^^^^^^^^^^^^^^^
|
||
Use the CREATE TABLE or ALTER TABLE commands and set the default_time_to_live value:
|
||
|
||
.. code-block:: cql
|
||
|
||
CREATE TABLE heartrate_ttl (
|
||
pet_chip_id uuid,
|
||
name text,
|
||
heart_rate int,
|
||
PRIMARY KEY (pet_chip_id))
|
||
WITH default_time_to_live = 600;
|
||
|
||
Here a TTL of 10 minutes is applied to all rows, however, keep in mind that TTL is stored on a per column level for non-primary key columns.
|
||
|
||
It’s also possible to change the default_time_to_live on an existing table using the ALTER command:
|
||
|
||
.. code-block:: cql
|
||
|
||
ALTER TABLE heartrate_ttl WITH default_time_to_live = 3600;
|
||
|
||
TTL with LWT
|
||
.............
|
||
|
||
.. include:: /rst_include/note-ttl-lwt.rst
|
||
|
||
Refer to :doc:`LWT </features/lwt/>` for more information.
|
||
|
||
The ``gc_grace_seconds`` parameter is defined :ref:`here <create-table-general-options>`.
|
||
|
||
|
||
|
||
TTL for a Collection
|
||
^^^^^^^^^^^^^^^^^^^^
|
||
|
||
You can set the TTL on a per element basis for collections.
|
||
|
||
See for example the :ref:`Maps <maps>` CQL Reference for map collections.
|
||
For a non-frozen map or set column, each element is stored independently and can have its own TTL. You can query the
|
||
remaining TTL for a specific map element using ``TTL(map_column[key])`` or for a specific set element using
|
||
``TTL(set_column[element])``:
|
||
|
||
.. code-block:: cql
|
||
|
||
CREATE TABLE t (pk int PRIMARY KEY, m map<int, int>, s set<int>);
|
||
INSERT INTO t (pk, m, s) VALUES (1, {1: 10}, {100}) USING TTL 3600;
|
||
UPDATE t USING TTL 7200 SET m = m + {2: 20}, s = s + {200} WHERE pk = 1;
|
||
|
||
-- Returns the remaining TTL for each map element independently
|
||
SELECT TTL(m[1]), TTL(m[2]) FROM t WHERE pk = 1;
|
||
|
||
-- Returns the remaining TTL for each set element independently
|
||
SELECT TTL(s[100]), TTL(s[200]) FROM t WHERE pk = 1;
|
||
|
||
Similarly, you can retrieve the write timestamp of a specific map element using ``WRITETIME(map_column[key])``
|
||
or of a specific set element using ``WRITETIME(set_column[element])``.
|
||
|
||
For a non-frozen user-defined type (UDT) column, each field is also stored independently and can have its own TTL.
|
||
You can query the remaining TTL or write timestamp of a specific field using dot notation:
|
||
``TTL(udt_column.field)`` and ``WRITETIME(udt_column.field)``.
|
||
|
||
See the :ref:`WRITETIME and TTL function <select-writetime-ttl>` section for details.
|
||
|
||
Notes
|
||
^^^^^
|
||
* Notice that setting the TTL on a column using UPDATE or INSERT overrides the default_time_to_live set at the Table level.
|
||
* The TTL is determined by the coordinator node. When using TTL, make sure that all the nodes in the cluster have synchronized clocks.
|
||
* When using TTL for a table, consider using the TWCS compaction strategy.
|
||
* ScyllaDB defines TTL on a per column basis, for non-primary key columns. It’s impossible to set the TTL for the entire row after an initial insert; instead, you can reinsert the row (which is actually an upsert).
|
||
* TTL can not be defined for counter columns.
|
||
* To remove the TTL, set it to 0.
|
||
|
||
|
||
|
||
Additional Information
|
||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||
|
||
To learn more about TTL, and see a hands-on example, check out `this lesson <https://university.scylladb.com/courses/data-modeling/lessons/advanced-data-modeling/topic/expiring-data-with-ttl-time-to-live/>`_ on ScyllaDB University.
|
||
|
||
* `Video: Managing data expiration with Time-To-Live <https://www.youtube.com/watch?v=SXkbu7mFHeA>`_
|
||
* :doc:`Apache Cassandra Query Language (CQL) Reference </cql/index>`
|
||
* :doc:`KB Article:How to Change gc_grace_seconds for a Table </kb/gc-grace-seconds/>`
|
||
* :doc:`KB Article:Time to Live (TTL) and Compaction </kb/ttl-facts/>`
|
||
* :ref:`CQL Reference: Table Options <create-table-general-options>`
|