在传统的三层架构中,应用为了降低数据库压力,通常会在业务层引入Redis或Memcached这样的外部缓存。这类方案虽然有效,但长期存在两个难以根治的问题:一是缓存与数据库之间的数据一致性维护成本高,需要业务代码自己处理失效、刷新和回源逻辑;二是缓存的查询能力有限,复杂SQL、多表关联、聚合分析往往无法直接在缓存层执行,最终还是要把压力压回数据库。Oracle 23ai引入的True Cache正是针对这两个痛点设计的解决方案,它让缓存层直接使用数据库自身的SQL引擎,应用几乎零改造就能获得接近内存级的查询速度。

True Cache的架构原理与核心特性
True Cache本质上是Oracle数据库的一个只读副本实例,但它与传统只读副本(Active Data Guardstandby)有本质区别。True Cache采用内存列式存储格式,查询结果直接从内存中的列式缓存池读取,避免了行式存储的解压与转换开销,对于分析型查询和宽表扫描场景,性能提升尤为明显。
它的数据同步机制基于底层的数据复制技术,主库的变更会持续推送到True Cache实例,缓存内的数据始终保持事务级一致。这意味着应用不再需要编写缓存失效逻辑:当主库数据提交后,True Cache中的对应数据会自动更新到最新状态。相比Redis方案中常见的“先更新数据库再删缓存”这类存在时间窗口的补丁式做法,一致性保障从根本上更强。
另一个关键特性是对应用的透明性。DBA在数据库层面定义表或物化视图是否启用缓存激活(cache activation),应用只需要在连接串中指定True Cache对应的service name,SQL语句就会自动路由到缓存实例执行。SQL的解析、优化、执行全部复用数据库内核,支持完整的SQL语法,包括关联、聚合、窗口函数等,这是任何外部缓存产品都无法做到的。
部署配置True Cache的具体步骤
True Cache的部署通常借助Oracle Fleet Patching and Provisioning(FPP)等自动化工具完成,也可以手工搭建。核心思路是先创建一个只读实例,再将其配置为True Cache角色。下面以关键SQL为例说明配置过程。
首先在主库上确认参数设置,True Cache要求使用OMF(Oracle Managed Files)并配置正确的DG_BROKER参数:
-- 主库参数设置 ALTER SYSTEM SET DG_BROKER_START=TRUE; ALTER SYSTEM SET db_create_file_dest='+DATA'; -- 查看当前实例角色 SELECT database_role, open_mode FROM v$database;
然后在True Cache实例上设置角色参数,并启动为只读模式:
-- True Cache实例设置 ALTER SYSTEM SET db_true_cache=TRUE; ALTER SYSTEM SET service_names='true_cache_svc'; SHUTDOWN IMMEDIATE; STARTUP MOUNT; ALTER DATABASE OPEN READ ONLY;
配置完成后,需要在主库上为需要缓存的表执行缓存激活操作。激活后,这张表的数据会被自动填充到True Cache的列式缓存中,并随主库变更持续同步:
-- 激活表的缓存,并指定填充优先级 ALTER TABLE sales ORDERS CACHE ACTIVATION; -- 基于查询结果激活,只缓存热点数据 ALTER TABLE sales MODIFY CACHE ACTIVATION FOR QUERY 'SELECT * FROM sales WHERE order_date > SYSDATE - 30';
可以看到,True Cache支持全表激活和基于查询谓词的选择性激活两种模式。对于数据量大但热点集中的表,使用FOR QUERY子句只缓存满足条件的行,能显著降低内存占用。
应用如何连接True Cache并验证效果
应用端的接入非常简单,只需要在JDBC连接串中将service name指向True Cache的service即可。由于缓存实例与主库共享同一套数据字典,应用可以使用与直连主库完全相同的用户名、密码和SQL。
// JDBC连接True Cache
String url = "jdbc:oracle:thin:@//dbhost:1521/true_cache_svc";
Connection conn = DriverManager.getConnection(url, "app_user", "password");
// SQL语句与直连主库完全一致,无需任何改写
PreparedStatement ps = conn.prepareStatement(
"SELECT region, SUM(amount) FROM sales GROUP BY region");
ResultSet rs = ps.executeQuery();
验证数据是否命中缓存,可以通过查询动态性能视图确认。在True Cache实例上执行下面的语句,能够看到各缓存对象的填充情况与命中统计:
-- 查看缓存对象激活状态 SELECT object_name, activation_status, populated FROM dba_true_cache_objects; -- 查看列式缓存的内存使用 SELECT * FROM v$inmemory_area;
此外,True Cache还支持方向性感知:应用可以连接一个同时代理主库和缓存的CMAN或监听配置,写操作自动路由到主库,读操作路由到缓存,实现读写分离的同时保证会话一致性。这种模式下,事务内的读会话仍会看到自己未提交的变更,避免了读写分离常见的自读问题。
适用场景与使用限制分析
True Cache最适合的场景是读多写少的业务:报表查询、大屏看板、商品详情页、历史数据检索等。这些场景的共同特点是查询模式相对固定、数据可以接受秒级以内的同步延迟、SQL复杂度较高。列式内存格式配合数据库优化器,对这类查询的加速效果通常能达到数倍到数十倍。
使用时也需要注意几点限制。第一,True Cache是只读的,所有写操作必须路由回主库,写密集型业务无法从中受益。第二,它是一个独立的Oracle数据库实例,需要额外的服务器内存资源,内存成本不低,因此在选型时应通过缓存命中率评估投入产出比。第三,数据同步存在极短延迟,对强一致读有硬性要求的查询应显式连接主库的service。第四,从现有版本升级迁移时,需要确认数据库版本满足True Cache的要求,并测试应用连接串的切换方案。
与Redis方案对比,True Cache省去了缓存层的数据建模和序列化开销,运维上也不需要维护两套技术栈的一致性逻辑,代价是整体方案被绑定在Oracle生态内。对于已经是Oracle重度的用户来说,这是一个非常自然的演进路径;而对于以开源技术栈为主、缓存需求简单键值化的团队,传统方案仍有其价值。技术选型没有绝对优劣,关键在于让缓存的复杂度与业务的一致性要求、SQL复杂度和团队运维能力相匹配。
Oracle 23aiTrue Cache数据库缓存修改时间:2026-09-01 09:12:36