All Products
Search
Document Center

PolarDB:Enable and use tiered storage for cold data

Last Updated:Mar 28, 2026

Tiered storage for cold data lets you move infrequently accessed database objects — tables, indexes, materialized views, and LOB fields — from local disk to OSS (Object Storage Service), reducing storage costs without requiring any changes to how your application queries data.

The typical workflow is:

  1. Check compatibility — Confirm your cluster version and region support the feature.

  2. Enable tiered storage — Turn on the feature from the PolarDB console (one-time, irreversible; triggers a cluster restart).

  3. Move data to cold storage — Use SQL statements to transfer objects to the OSS tablespace.

  4. Configure the materialized cache — Tune polar_smgrcache_size to cache frequently accessed cold data locally and reduce OSS read latency.

  5. Query and manage cold data — Run standard DML/DQL statements; no application changes required.

Applicability

Version requirements

PolarDB for PostgreSQL versionMinimum minor engine version
PostgreSQL 162.0.16.9.6.0
PostgreSQL 142.0.14.10.21.0
Individual cold storage for LOB fields is not supported on PostgreSQL 16.

Supported regions

AreaRegion
ChinaChina (Hangzhou)
ChinaChina (Shanghai)
ChinaChina (Shenzhen)
ChinaChina (Beijing)
OtherSingapore

Limitations

Enabling the feature is irreversible. Once enabled, tiered storage cannot be disabled. To remove cold data, delete the objects stored in OSS. If no cold data is stored, you are not charged for the feature.

Clusters with hot standby have restrictions. You cannot enable tiered storage on a PolarDB for PostgreSQL cluster that has hot standby enabled. To enable the feature in this scenario, contact us for assistance.

Changing the primary zone requires assistance. After tiered storage is enabled on a cluster with hot standby, you cannot change the primary zone directly. Contact us for assistance.

Some DDL statements are unsupported:

  • CREATE DATABASE dbname TABLESPACE OSS; — Creating a database directly in the OSS tablespace is not supported.

  • ALTER DATABASE dbname SET TABLESPACE OSS; — Transferring an entire database to the OSS tablespace with a single command is not supported.

Enable tiered storage

Important

Enabling tiered storage restarts the PolarDB cluster. Schedule this operation during a maintenance window.

  1. Log on to the PolarDB console. In the left navigation pane, click Clusters. Select the region where your cluster is located, find the cluster, and click its ID.

  2. In the left navigation pane, choose Settings And Management > Cold Data Tiered Storage.

  3. On the PolarDB cold data tiered storage page, click Enable.

    Cold data tiered storage enable page

    After enabling, the Archive List page appears. It contains an Overview section and a Data Archive List section. The Data Archive List section has three tabs: Whole table Archive list, Partition Table Archive List, and LOB Field Archive List.

    If no cold data has been transferred yet, the Data Archive List is empty. Data remains on high-speed disk storage by default until you explicitly move it to the OSS tablespace.

Move data to cold storage

After enabling the feature, move data to the OSS tablespace using SQL statements. All subsequent DML and DQL operations on objects in the OSS tablespace are transparent — no application changes are required.

Standard tables, indexes, and materialized views

Move existing objects to cold storage:

ALTER TABLE tblname SET TABLESPACE OSS;
ALTER INDEX idxname SET TABLESPACE OSS;
ALTER MATERIALIZED VIEW mvname SET TABLESPACE OSS;
ALTER TABLE tblname SET TABLESPACE OSS transfers only the table data. To also move the table's indexes, run ALTER INDEX separately for each index.

Create new objects directly in cold storage:

Method 1: Specify TABLESPACE OSS in the CREATE statement.

CREATE TABLE tblname (...) TABLESPACE OSS;
CREATE TABLE tblname (...) TABLESPACE OSS AS SELECT ...;
CREATE INDEX idxname ON tblname (columnname) TABLESPACE OSS;
CREATE INDEX idxname ON tblname USING GiST (columnname) TABLESPACE OSS;
CREATE MATERIALIZED VIEW table_name TABLESPACE OSS AS query [ WITH [ NO ] DATA ];

Method 2: Set the session's default tablespace to oss before creating objects.

SET default_tablespace = 'oss';
CREATE TABLE tblname (...);
CREATE INDEX idxname ON tblname (columnname);
CREATE MATERIALIZED VIEW table_name AS query [ WITH [ NO ] DATA ];

After setting default_tablespace = 'oss', all CREATE TABLE, CREATE INDEX, and CREATE MATERIALIZED VIEW statements in the session create objects directly in the OSS tablespace. To stop creating objects in cold storage, reset the default:

RESET default_tablespace;

LOB fields

Individual cold storage for LOB fields is not supported on PostgreSQL 16.

LOB fields — including blob, text, json, jsonb, array, and spatio-temporal data types — are often large and infrequently updated. You can move only the LOB fields to cold storage while keeping all other columns on local disk.

-- Create a table with a LOB field.
CREATE TABLE test_large_object (id serial, val text);

-- Move the LOB field to cold storage.
ALTER TABLE test_large_object ALTER COLUMN val SET (storage_type = 'oss');

-- New data written to this field is now stored in OSS.
INSERT INTO test_large_object (val)
VALUES ((SELECT string_agg(random()::text, ':') FROM generate_series(1, 10000)));
Important

Set storage_type = 'oss' on the column before writing data. Only data written after this change is stored in OSS; existing data is not migrated retroactively.

Partitioned tables

Partitioned tables are a common use case for cold storage. You can move all partitions or only specific expired partitions to the OSS tablespace.

Move all partitions to cold storage:

Method 1: Run ALTER TABLE ... SET TABLESPACE OSS on each child partition.

-- prt1 is the parent partitioned table.
-- prt1_p1 and prt1_p2 are child partitions.
ALTER TABLE prt1_p1 SET TABLESPACE OSS;
ALTER TABLE prt1_p2 SET TABLESPACE OSS;

Method 2: Create the parent table in the OSS tablespace. Child partitions inherit the tablespace.

CREATE TABLE prt1 (a int, b int) PARTITION BY RANGE (a) TABLESPACE OSS;

-- Child partitions inherit the OSS tablespace from the parent.
CREATE TABLE prt1_p1 PARTITION OF prt1 FOR VALUES FROM (0) TO (250);
CREATE TABLE prt1_p2 PARTITION OF prt1 FOR VALUES FROM (250) TO (500);

Method 3: Set default_tablespace = 'oss' before creating the partitioned table.

SET default_tablespace = 'oss';
CREATE TABLE prt1 (a int, b int) PARTITION BY RANGE (a);
CREATE TABLE prt1_p1 PARTITION OF prt1 FOR VALUES FROM (0) TO (250);
CREATE TABLE prt1_p2 PARTITION OF prt1 FOR VALUES FROM (250) TO (500);

Move only expired partitions to cold storage:

To reduce costs without affecting query performance on active partitions, move only expired (infrequently accessed) child partitions to the OSS tablespace. Active partitions remain on local disk.

-- prt1_p1 is an active child partition — leave it on disk.
-- prt1_p2 is an expired child partition — move it to OSS.
ALTER TABLE prt1_p2 SET TABLESPACE OSS;

Configure the materialized cache

The materialized cache stores frequently accessed cold data blocks on local disk, reducing OSS read latency. When tiered storage is enabled, a small default cache is created automatically to store metadata and handle I/O merging.

Tune the cache size using the polar_smgrcache_size parameter:

ValueCache size
0Disabled
11 GB
22 GB
128128 GB (maximum)

To modify the parameter:

  1. In the PolarDB console, go to the cluster details page.

  2. In the left navigation pane, choose Settings And Management > Parameters.

  3. Find polar_smgrcache_size and click Modify.

  4. Set the value, then click Submit Changes in the upper-left corner. In the Save Changes dialog, click OK.

The cluster restarts and the new cache size takes effect.

Warning

If you set polar_smgrcache_size to 0 after cold data is in active use, the cache is disabled. This can cause crash recovery to become very slow, and the parameter cannot be re-enabled during the restart. To recover, contact us to request that the cache be re-enabled.

Monitor cache usage:

-- Install the monitoring extension.
CREATE EXTENSION polar_monitor;

-- Query current cache usage.
SELECT * FROM polar_smgrcaches;

The polar_smgrcaches view returns the following fields:

FieldDescription
smgrcacheCache ID
relfilenodeTable file associated with this cache entry
relchunknumberPosition of the cache entry in the table file
nblocksSize of the cache entry (in blocks)
dirtyWhether the cache entry contains dirty blocks
usagecountUsage count
pinning_backendsReference count

To manage the cache manually:

-- Flush all cache entries to OSS.
SELECT polar_flush_smgrcache();

-- Evict all cache entries from local disk.
SELECT polar_evict_smgrcache();

Query and manage cold data

Query cold data

DML and DQL statements on objects in the OSS tablespace are fully transparent — no SQL changes or application modifications are required. Standard SELECT, INSERT, UPDATE, and DELETE statements work the same way as on local tables.

Restore cold data to local disk

Data is compressed when transferred to OSS. If you need to move data back to a local disk tablespace, make sure the target disk has enough free space. The space required is typically 1.4 to 4 times the storage space that the data occupies on OSS.

Delete cold data

SQL statements for deleting cold tables, indexes, or materialized views work the same as for local objects:

DELETE FROM tblname WHERE ...;
TRUNCATE TABLE tblname;
DROP TABLE tblname;