All Products
Search
Document Center

Lindorm:Separate hot and cold data based on a custom time column

Last Updated:Mar 28, 2026

When your table uses a business timestamp (such as event time or transaction time) to classify data age—rather than the system write time—you can configure LindormTable to tier hot and cold data based on that column. LindormTable archives entire rows to cold storage when the value in the custom time column crosses the configured boundary. Recent rows stay in fast storage for low-latency queries; older rows move to cold storage to reduce costs. Because hot and cold data remain in the same table, queries transparently route to the correct storage tier when you filter on the custom time column.

Prerequisites

Before you begin, make sure you have:

Constraints

  • This feature is supported only for Lindorm SQL. HBase-compatible operations are not supported.

  • When a row's value in the custom time column crosses the hot data boundary, the entire row is archived to cold storage.

  • The custom time column must satisfy all of the following conditions:

    • It must be a primary key column.

    • It cannot be the first column of the primary key.

    • Its data type must be BIGINT or TIMESTAMP. If the column does not exist, has no data, or contains data of an incorrect type, all data is written to hot storage.

Configure hot and cold data separation for a table

Step 1: Set the custom time column and data boundary

Choose one of the following methods based on whether the table already exists.

Method 1: Set when creating the table

The following examples create a table named dt with a one-day hot and cold data boundary, using column p2 as the custom time column.

Note

The custom time column (p2 in these examples) must be a primary key column but cannot be the first primary key column.

-- Default time unit: milliseconds (ms)
CREATE TABLE dt (p1 integer, p2 bigint, p3 bigint, c1 varchar, constraint pk PRIMARY KEY(p1, p2, p3))
WITH(COMPRESSION = 'ZSTD', CHS ='86400', CHS_L2 = 'storagetype=COLD', CHS_COLUMN = 'COLUMN=p2');

-- Set time unit to seconds (s)
CREATE TABLE dt (p1 integer, p2 bigint, p3 bigint, c1 varchar, constraint pk PRIMARY KEY(p1, p2, p3))
WITH(COMPRESSION = 'ZSTD', CHS ='86400', CHS_L2 = 'storagetype=COLD', CHS_COLUMN = 'COLUMN=p2|TIMEUNIT=SECONDS');

-- Set time unit to minutes (min)
CREATE TABLE dt (p1 integer, p2 bigint, p3 bigint, c1 varchar, constraint pk PRIMARY KEY(p1, p2, p3))
WITH(COMPRESSION = 'ZSTD', CHS ='86400', CHS_L2 = 'storagetype=COLD', CHS_COLUMN = 'COLUMN=p2|TIMEUNIT=MINUTES');
Important

Do not add spaces on either side of the equal sign (=) in CHS_COLUMN. For example, use COLUMN=p2, not COLUMN = p2. Spaces cause an error.

ParameterDescription
CHSThe hot and cold data boundary, in seconds. Data older than this threshold (based on the custom time column) is archived to cold storage during compaction. For example, 86400 = 86,400 seconds = 1 day.
CHS_L2The layer-2 storage property. Set to storagetype=COLD to direct archived data to cold storage.
CHS_COLUMNThe custom time column and its time unit. Format: COLUMN=<column_name>|TIMEUNIT=<unit>. The default unit is milliseconds (ms). Supported units: SECONDS, MINUTES, MICROSECONDS, NANOSECONDS.
COMPRESSIONThe compression algorithm for the table. Not case-sensitive. Defaults to none.

Method 2: Add separation to an existing table

Use ALTER TABLE to enable hot and cold data separation on a table created without it.

-- Enable hot and cold data separation with a one-day boundary, using p2 (default unit: milliseconds)
ALTER TABLE dt SET 'CHS' ='86400', 'CHS_L2' = 'storagetype=COLD', 'CHS_COLUMN' = 'COLUMN=p2';

-- Use p2 with time unit set to seconds
ALTER TABLE dt SET 'CHS' ='86400', 'CHS_L2' = 'storagetype=COLD', 'CHS_COLUMN' = 'COLUMN=p2|TIMEUNIT=SECONDS';

-- Use p2 with time unit set to minutes
ALTER TABLE dt SET 'CHS' ='86400', 'CHS_L2' = 'storagetype=COLD', 'CHS_COLUMN' = 'COLUMN=p2|TIMEUNIT=MINUTES';

Verify the configuration

Use either of the following methods to confirm the settings:

  • Run SHOW TABLE VARIABLES FROM dt LIKE 'CHS_COLUMN'; to view the table properties.

  • In the cluster management system, go to the Overview page and click the table name. In the Current Table Details area, check the values of CHS and CHS_COLUMN.

Step 2 (Optional): Modify the configuration

Modify the hot and cold data boundary:

ALTER TABLE dt SET 'CHS'='1000';

Modify the custom time column:

ALTER TABLE dt SET 'CHS_COLUMN'='COLUMN=p3';

Step 3 (Optional): Disable hot and cold data separation

ALTER TABLE dt SET 'CHS'='', 'CHS_L2' = '', 'CHS_COLUMN'='';
Note

After you modify the boundary or disable separation, data does not immediately move from cold storage back to hot storage. The system waits for a background compaction to complete. To return data to hot storage immediately, run a major compaction manually using the major_compact command.

Configure hot and cold data separation for a secondary index

A secondary index is stored within the base table, so you configure it the same way. The following examples use the dt table created in the previous section.

Note

For a secondary index, CHS_COLUMN must reference the same custom time column as the base table. You cannot specify a different column.

Create a secondary index with separation enabled

Method 1: Set when creating the secondary index

CREATE INDEX idx ON dt (c1) WITH(CHS = '86400', CHS_L2 = 'storagetype=COLD', CHS_COLUMN='COLUMN=p2');

Method 2: Add separation to an existing secondary index

-- Enable hot and cold data separation on an existing index
ALTER TABLE `dt.idx` SET 'CHS' = '86400', 'CHS_L2' = 'storagetype=COLD', 'CHS_COLUMN'='COLUMN=p2';
Note

A secondary index table name uses the format TableName.IndexName. Because the period (.) is a special character, enclose the name in backticks (`). For example, write `dt.idx`, not dt.idx.

Modify or disable the secondary index configuration

Modify the hot and cold data boundary:

ALTER TABLE `dt.idx` SET 'CHS'='10000';

Modify the custom time column:

ALTER TABLE `dt.idx` SET 'CHS_COLUMN'='COLUMN=p2';

Disable separation:

ALTER TABLE `dt.idx` SET 'CHS'='', 'CHS_L2' = '', 'CHS_COLUMN'='';

Write data

Writing data to a table with hot and cold data separation enabled works the same as writing to a standard table. Data is initially stored in hot storage (Medium or Compute-optimized). A row is archived to cold storage during compaction when the following condition is met:

Current time - Value of the time column > Value of CHS

Query data

Hot and cold data reside in the same table. All queries target that single table. When you filter on the custom time column with a time range, LindormTable uses it to determine whether to scan hot storage, cold storage, or both—so the query only reads the relevant tier. Without a time range filter, the query may hit cold data, and throughput is limited by cold storage capacity. For details, see Storage-optimized Lindorm instances.

To query only hot data when you cannot filter on the custom time column, use the _l_hot_only_ hint.

Query examples

Random query (Get)

-- p2 is the custom time column
SELECT * FROM dt WHERE p1 = 10 AND p2 = 10;

Range query

-- p2 is the custom time column
SELECT * FROM dt WHERE p2 > 10 AND p2 < 1000;
Important

By default, LindormTable does not run a SELECT statement identified as an inefficient query—it throws an exception instead. For details, see SELECT.

Query only hot data using a hint

SELECT /*+ _l_hot_only_(true) */ * FROM dt WHERE p1 > 1;

Example: Internet of Vehicles scenario

In Internet of Vehicles (IoV) scenarios, the primary key typically consists of vin (Vehicle Identification Number) and ts (timestamp). Define ts as the custom time column. When querying data for a specific vehicle within a time range, LindormTable automatically determines whether to access hot or cold storage based on the query conditions.

USE test;
CREATE TABLE dt (
  vin varchar, ts bigint, c1 varchar, c2 varchar,
  constraint pk primary key(vin, ts)
) WITH (COMPRESSION = 'ZSTD', CHS ='86400', CHS_L2 = 'storagetype=COLD', CHS_COLUMN = 'COLUMN=ts');

-- Query data for a specific vehicle within a time range
SELECT * FROM dt WHERE vin = 'xxxx' AND ts > 1675065122000 AND ts < 1675975222000;

FAQ

If I update existing cold data, does the updated data remain cold?

Yes, if the update does not change the value in the custom time column. If the value changes, LindormTable re-evaluates the row's hot/cold status based on the new value.

For example: a table has primary key columns p1 and p2, and non-primary key columns c1 and c2. A row has values p1=row1, p2=Jan-28-2023, c1="c1", c2="c2". With a 1-day boundary (CHS) and a current date of Jan-30-2023, the row is cold. Updating c1 or c2 keeps the row cold. Updating p2 to Jan-30-2023 makes the row hot, and it becomes cold again on Feb-01-2023.

Note

You cannot update the value of a custom time column that is part of the primary key.

If a row has no value in the custom time column, is the data separated?

No. Rows with no value in the custom time column are kept in hot storage.