Table size caching (RSC)
PolarDB for PostgreSQL (Compatible with Oracle) caches table and index block counts in shared memory to reduce file system calls during SQL execution, significantly lowering query latency.
Use cases
Table size caching benefits workloads where:
High read-to-write ratio: Queries repeatedly scan the same tables, making cache hits frequent and latency savings significant.
Distributed storage: The cluster uses PolarFS (Polar File System), where each
lseekcall to get file size carries higher latency than on centralized file systems.Latency-sensitive applications: SQL execution latency must stay in the sub-microsecond range for block count lookups.
Prerequisites
Before you begin, ensure that you have:
PolarDB for PostgreSQL (Compatible with Oracle) 2.0, revision version 2.0.14.12.23.1 or later
View the revision version in the console or by running SHOW polardb_version;. Upgrade the revision version if needed.How it works
RSC architecture
The Relation Size Cache (RSC) is built into the storage manager (smgr) and lives in shared memory. It consists of two structures:
One-dimensional array: Each entry stores the block count for one relation (a table or index).
Hash table: Maps each relation's identifier (RelFileNode) to its entry in the array. A RelFileNode uniquely identifies a relation at the storage layer.
Query flow
All processes query the RSC using two levels of indexes before falling back to the file system:
Level 1 index: Each process caches pointers to recently accessed RSC entries along with their generation numbers. On a lookup, the process checks whether the pointer matches the requested relation and whether the generation number is unchanged. If both conditions hold, the process reads the block count directly from the pointer. This level delivers a high hit ratio for read-heavy workloads. When the RSC hash table is updated, the generation numbers of affected entries are automatically incremented, invalidating any stale level 1 pointers.
Level 2 index: On a level 1 cache miss, the process queries the hash table in shared memory to locate the RSC entry. Once found, it reads the block count and updates the level 1 index for future lookups.
If neither level finds the relation, cache replacement is triggered. The RSC uses the Segmented Least Recently Used (SLRU) algorithm to evict a rarely used entry, calls lseek on the file system to get the actual block count, writes the result to the evicted slot, and updates both indexes.
RSC updates on the primary node
Any smgr function that changes a table's size also updates the corresponding RSC entry in shared memory synchronously, keeping the cached block count consistent with the actual file size:
Extending a table: The new block count is written to the RSC immediately.
Truncating a table: The updated block count is written to the RSC immediately.
RSC updates on standby nodes
Standby nodes use physical replication to stay in sync with the primary node. During WAL (Write Ahead Log) replay, standby nodes invoke the same smgr functions used on the primary node, so RSC updates on standby nodes are handled identically to those on the primary node.
RSC updates on replica nodes
Replica nodes share physical storage with the primary node and sync via log indexes. Because replica nodes are read-only, they cannot call smgr functions to update the RSC directly.
Instead, replica nodes parse WAL records to detect storage changes:
Block count increase: If a WAL record references a block sequence number higher than the cached count, the RSC entry is updated to the actual block count.
Cache invalidation: If a WAL record indicates a table truncation, the cached block count is invalidated. The next file system call for that table repopulates the RSC with the actual count.
GUC parameters
The following Grand Unified Configuration (GUC) parameters control the RSC. Valid values for all parameters: on | off.
| Parameter | Description | Default |
|---|---|---|
polar_enable_rel_size_cache | Enables the RSC feature. | on |
polar_enable_replica_rel_size_cache | Enables the RSC for replica nodes. | on |
polar_enable_standby_rel_size_cache | Enables the RSC for standby nodes. | on |
Performance benchmarks
The following results show the block count query latency for a 32-GB table with RSC disabled and enabled.
RSC disabled — latency ~55 microseconds:
SHOW polar_enable_rel_size_cache;
polar_enable_rel_size_cache
-----------------------------
off
(1 row)
SELECT polar_smgrperf_nblocks(32, true, false);
NOTICE: testing logical file length with 32 GB
INFO: iops=18341.1/s, lat=54.52us
INFO: iops=17504.0/s, lat=57.13us
INFO: iops=17960.8/s, lat=55.68us
INFO: iops=17973.0/s, lat=55.64us
INFO: iops=17603.5/s, lat=56.81us
INFO: iops=17403.8/s, lat=57.46us
INFO: iops=17506.2/s, lat=57.12us
INFO: iops=18061.7/s, lat=55.37usRSC enabled — latency ~0.07 microseconds:
SHOW polar_enable_rel_size_cache;
polar_enable_rel_size_cache
-----------------------------
on
(1 row)
SELECT polar_smgrperf_nblocks(32, true, false);
NOTICE: testing logical file length with 32 GB
INFO: iops=14155515.6/s, lat=0.07us
INFO: iops=13897273.6/s, lat=0.07us
INFO: iops=13869926.3/s, lat=0.07us
INFO: iops=13779602.7/s, lat=0.07us
INFO: iops=14159120.5/s, lat=0.07us
INFO: iops=14147065.6/s, lat=0.07us
INFO: iops=14124141.9/s, lat=0.07us
INFO: iops=14162773.3/s, lat=0.07usWith RSC enabled, block count lookups are approximately 800x faster, eliminating the file system call from the critical SQL execution path.