All Products
Search
Document Center

PolarDB:TTL archiving

Last Updated:Sep 20, 2026

TTL archiving extends the TTL feature by writing expired data to a separate archive table and migrating it to OSS cold storage, enabling tiered storage of hot and cold data.

Overview

Standard TTL works as follows: the background purge thread scans for expired rows and deletes them directly. The deleted data cannot be recovered.

TTL archiving adds an extra step. Within the same transaction that deletes expired rows from the source table, the rows are first inserted into the corresponding archive table. Over time, older partitions are automatically migrated to OSS in the background. This creates a tiered storage structure where hot data resides in the source table and cold data resides in the archive table or OSS.

Key semantics to understand:

  • The source table and the archive table are two physically independent tables:

    • There is no automatic UNION or query rewriting. SELECT * FROM source_table reads only the source table and does not return archived data.

    • To query archived data, you must explicitly query the archive table.

  • The archive table is always named <source_table_name>__ttl_archived__.

  • Cold partitions that have been migrated to OSS are invisible to regular queries by default. The WITH ARCHIVED modifier is required to include them in scans. For details, see Query archived data.

  • Archive writes and source table deletions occur within the same transaction, ensuring atomicity: either both the source table deletion and the archive write succeed, or both are rolled back. There is no intermediate state where "the source row was deleted but the archive write failed" (with the exception of backfilling historical data; for details, see Usage notes).

Scope of application

  • Cluster version: The cluster must run MySQL 8.0.2 with a minor engine version of 8.0.2.2.37 or later.

  • Parameter configuration: To enable TTL archiving, all of the following conditions must be met. If any condition is not met, CREATE TABLE or ALTER TABLE statements with the archiving attribute are rejected. You can enable the following parameters on the Parameters page in the console.

    Condition

    Parameter

    Description

    Enable the archiving master switch

    loose_innodb_ttl_archived_enable = ON

    When OFF, DDL statements with the archiving attribute are rejected, and the purge thread does not archive expired rows

    Enable OSS capability

    loose_polar_oss_enable = ON

    Cold partitions of the archive table must be migrated to OSS. This is enforced during table creation

    Enable TTL purge

    loose_innodb_enable_ttl_purge = ON

    Archiving is driven by the TTL purge thread

Syntax

Create a TTL table with the archiving attribute

Append the ARCHIVED flag to the standard TTL syntax. Two equivalent formats are supported.

Syntax

  • Format 1: Compact string TTL='column@interval_seconds@ARCHIVED'

    CREATE TABLE `t1` (
      `a` INT PRIMARY KEY,
      `b` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
      KEY idx_b (`b`)
    ) ENGINE=InnoDB TTL='b@5@ARCHIVED';
  • Format 2: INTERVAL syntax TTL='column' + INTERVAL n unit AND ARCHIVED

    CREATE TABLE `t1` (
      `a` INT PRIMARY KEY,
      `b` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
      KEY idx_b (`b`)
    ) ENGINE=InnoDB TTL='b' + INTERVAL 3 HOUR AND ARCHIVED;

Notes

  • The ARCHIVED flag is case-insensitive, but only the complete word archived is accepted. Abbreviated forms such as @archiv or @ARCHIV cause an error.

  • The time units supported by INTERVAL are the same as those for standard TTL: YEAR / QUARTER / MONTH / WEEK / DAY / HOUR / MINUTE / SECOND.

  • The INTERVAL here specifies the expiration duration of data, which is a separate concept from the Partition granularity of the archive table.

Add or remove the archiving attribute for an existing table

-- Add archiving to an existing TTL table (two equivalent formats)
ALTER TABLE `t2` TTL='b@5@archived';
ALTER TABLE `t2` TTL='b' + INTERVAL 5 SECOND AND ARCHIVED;

-- Remove the archiving attribute, keep standard TTL
ALTER TABLE `t2` TTL='b@5';

-- Remove TTL entirely (including archiving)
ALTER TABLE `t2` TTL='';
Note

When you remove the archiving attribute or clear TTL, the existing archive table is not deleted immediately. Instead, it is reclaimed by the background purge thread at a later time. This prevents data from being destroyed prematurely during the ALTER operation and avoids holding locks that block other DDL statements for an extended period. To retain historical archived data, back up or rename the archive table before removing the attribute.

View the archiving attribute of a table

SHOW CREATE TABLE `t1` FULL;

The FULL option is required to display complete TTL and archiving information.

Query archived data

The archive table is a regular visible table and can be queried directly. To read cold partitions that have been migrated to OSS, add WITH ARCHIVED:

-- Read only archived partitions that are still local
SELECT a, b FROM t1__ttl_archived__ ORDER BY a;

-- Read including cold partitions that have been migrated to OSS
SELECT a, b FROM t1__ttl_archived__ WITH ARCHIVED ORDER BY a;

Key semantics:

  • WITH ARCHIVED is a table-reference-level modifier that applies only to the table it directly annotates. You cannot write SELECT * FROM source_table WITH ARCHIVED to transparently read archived data.

  • The session variable prune_archived_oss_partitions (default: ON) controls whether OSS cold partitions are pruned. When set to OFF, a regular SELECT (without WITH ARCHIVED) also returns cold partitions.

Note

The WITH ARCHIVED syntax and the prune_archived_oss_partitions variable are not introduced by TTL archiving. They are general mechanisms provided by the underlying OSS partition archiving capability. TTL archive tables, as partitioned tables, reuse this visibility control.

Archive table structure

The archive table is automatically derived from the source table structure and is named <source_table_name>__ttl_archived__. It differs from the source table in the following ways:

  1. The primary key is a composite key of "source table primary key + TTL column". If the TTL column is already part of the source table primary key, it is not appended again. The TTL column becomes implicitly NOT NULL because it is part of the primary key.

  2. UNIQUE indexes on the source table are downgraded to regular (non-unique) indexes in the archive table. This is because the archive table silently skips duplicate primary keys (for details, see Usage notes), and retaining the UNIQUE constraint would conflict with this behavior.

  3. The archive table is RANGE-partitioned by the TTL time column. Partition names follow the format ARCHIVED_PARTITION_<upper_bound>. The partition window size is determined by the Partition granularity parameter.

Partition granularity

loose_innodb_ttl_archived_interval_type controls the time window size for partitioning the archive table (independent of the data expiration duration):

Value

Partition window

DAY (default)

Daily

WEEK

Weekly

MONTH

Monthly (30 days)

YEAR

Yearly (365 days)

A larger partition window results in fewer partitions and larger batches migrated to OSS. A smaller window creates more partitions and migrates cold data more promptly. Choose based on your data volume and query patterns. In most cases, the default DAY is sufficient.

Parameters

Archiving-specific parameters

Parameter

Scope

Type

Default

Description

loose_innodb_ttl_archived_enable

Global

BOOL

OFF

Archiving master switch. When OFF, DDL statements with the archiving attribute are rejected, and expired rows are not archived

loose_innodb_ttl_archived_interval_type

Global

ENUM

DAY

Archive partition granularity (DAY / WEEK / MONTH / YEAR)

Note

Cold partition visibility is controlled by the session variable prune_archived_oss_partitions (for details, see Query archived data). This variable belongs to the underlying OSS partition archiving capability and is not specific to TTL archiving, so it is not listed separately here.

General parameters required by archiving

Parameter

Default

Description

loose_polar_oss_enable

--

Must be ON. Prerequisite for archiving cold partitions to OSS

loose_innodb_enable_ttl_purge

OFF

TTL purge master switch. Archiving is driven by the purge thread

loose_innodb_ttl_purge_thread

4

Number of TTL purge threads

loose_innodb_ttl_min_interval

100

Minimum allowed TTL expiration duration (seconds)

loose_innodb_ttl_purge_start_hour / loose_innodb_ttl_purge_end_hour

0 / 0

Time window during which purge is allowed to run

loose_innodb_ttl_can_use_datetime

OFF

Allow the TTL column to be of the DATETIME type

loose_innodb_ttl_finished_job_expired_days

90

Retention period (days) for mysql.ttl_job_history records

Limits

When creating or altering a table with the archiving attribute, the following conditions trigger the error ER_TTL_INFO_CHECK_ERR (9913) (message template: TTL info check err:%s):

Scenario

Error message

Resolution

Archiving master switch is not enabled

TTL ARCHIVE requires innodb_ttl_archived_enable to be ON.

Set loose_innodb_ttl_archived_enable=ON first

OSS is not enabled

TTL ARCHIVE requires polar_oss_enable to be ON.

Set loose_polar_oss_enable=ON first

No explicit primary key

TTL ARCHIVE requires an explicit PRIMARY KEY.

Define an explicit PRIMARY KEY for the table before enabling archiving

Archive table name exceeds 64 characters

TTL ARCHIVE table name is too long, ...

Shorten the source table name so that source table name + __ttl_archived__ is within 64 characters

Contains virtual column indexes or multi-valued indexes

TTL ARCHIVE is not supported on tables with indexes on virtual columns or multi-valued indexes.

Remove virtual column indexes or multi-valued indexes

Contains FULLTEXT indexes

TTL is not supported on tables with FULLTEXT indexes.

Remove FULLTEXT indexes

Contains SPATIAL indexes

TTL is not supported on tables with SPATIAL indexes.

Remove SPATIAL indexes

Contains spatial columns (GEOMETRY, POINT, etc.)

TTL is not supported on tables with spatial columns.

Remove spatial columns

TTL column name contains @

TTL column name must not contain '@'.

Rename the TTL column to remove the @ character

TTL column does not exist or type mismatch

TTL column err; column[...] must exist and it's type should be TIMESTAMP or DATETIME(...)

Verify that the TTL column exists and is of the TIMESTAMP or DATETIME type

Expiration duration is less than the minimum

'ttl_interval' should be integer and bigger than innodb_ttl_min_interval.

Increase the expiration duration. It must be greater than innodb_ttl_min_interval (default: 100 seconds)

All of the above are scenarios where the kernel forcibly rejects the operation during table creation or alteration. The requirement that "the TTL column must be of the TIMESTAMP or DATETIME type" also applies to standard TTL (DATETIME requires loose_innodb_ttl_can_use_datetime=ON).

Usage notes

  • Backfilled historical data may be lost: If you backfill a batch of data with very old timestamps into a table that already has archiving enabled, the corresponding archive partitions may have already been migrated to OSS. In this case, after these rows expire and are deleted from the source table, the archive writes are silently discarded (the source table deletion still occurs as usual), resulting in data loss. Avoid backfilling data with timestamps earlier than the current OSS cold partition boundary into an archived table. If backfilling is necessary, first evaluate whether the target partition has already been migrated to OSS.

  • Duplicate primary keys are silently skipped: The archive table keeps the first written version. When a duplicate primary key (identical composite primary key) is encountered, it is silently skipped without an error.

  • Rows with NULL TTL column values never expire and therefore are never archived.

  • The archive table is writable but subject to visibility controls: Archive partitions can still be written to. WITH ARCHIVED only affects SELECT visibility and does not affect the scope of UPDATE or DELETE operations.

  • Recovery scenarios: When performing database or backup recovery, we recommend that you set loose_innodb_enable_ttl_purge to OFF first to prevent recovered data from being immediately purged or archived due to expiration.

  • No Binlog writing: Consistent with standard TTL, archiving-related deletions or writes are not recorded in the Binlog. The primary and replica nodes each rely on their own purge threads for execution. Do not rely on Binlog replication for archiving results.

Observability

The mysql.ttl_job_history table records each TTL purge task (job_id / table_name / state / start_time / finished_time / expire_time / scan_cost / purge_cost / purge_rows, etc.). Archiving events (migration success or failure, discards, duplicate primary key skips) are written to the instance error log. Use the log to troubleshoot archiving behavior.