在实际的数据库运维工作中,我们经常碰到一种非常“上头”的情况:同一套业务系统,既要支撑线上无数个小订单的写入和修改,又要扛住后台每天凌晨跑出来的年度报表或大数据分析。这类混合负载让数据库CPU和IO一会儿高一会儿低,如果架构设计得不好,就会出现线上操作卡顿,报表却跑不出来的尴尬局面。

在Oracle的世界里,解决这类问题通常离不开两个核心武器:RAC(Real Application Clusters)和Data Guard(简称DG)。很多人一上来就问:“RAC和Data Guard到底选哪个?”但真实的生产环境根本不会让你做单选题,它们俩通常是搭配着出现的。我们要用大白话聊聊,在混合负载的场景下,怎么把它们俩合理地摆在一起,让数据库既能跑得快,又能稳得住。

一、先别急着搭环境,想想你要解决什么问题

混合负载,说白了就是一套数据库同时要伺候两种性格完全不同的业务。一种是OLTP型,也就是那些频繁的小增删改查,比如收银台刷一下、点个按钮存个数据,每次操作虽然不大,但次数多,要求响应快。另一种是OLAP型,也就是那种大查询,比如跑一个月度销售报表,可能要把几千万条记录翻出来做聚合计算,CPU和磁盘直接拉满。

如果这两类业务共用一个普通单机数据库,很容易出现“大查询把资源抢光,小事务等得发飙”的情况。所以,我们需要一套更聪明的架构,让慢的查询别挡着快的交易。Oracle的RAC和Data Guard就是这套架构里的主角。

二、两个老伙计:RAC和Data Guard到底能干点啥

RAC像是一群兄弟共用同一套账本。每一台服务器(节点)都连着同一个数据库存储,大家同时对外提供服务。它的好处是:一个节点出了毛病,其他节点能立刻接手,业务不会断。同时,多个节点可以分担流量,比如两个节点的RAC,每个节点扛一半的并发请求。

Data Guard更像是主账房和分账房的关系。主库把每一笔日志实时或准实时地送到备库,备库可以打开成只读状态,帮忙查一些大而重的数据。而主库一旦崩了,备库还能顶上,成为新的主库,这就是我们常说的主备切换。

这里有个关键点要提醒大家:普通Data Guard的备库是不能一边同步一边查数据的。只有Oracle Active Data Guard(ADG)才允许备库在日志应用的同时,对外提供只读查询和报表查询。ADG是收费的,需要额外买许可。你要是想用备库来分担报表查询,就得确认好自己有没有这个许可,不然就是违规使用。

三、混合负载下,最主流的两种部署思路

3.1 思路一:把备库当作“查询回收站”

这种思路最简单粗暴:线上所有OLTP小事务都扔给RAC主库,后台那些慢得要命的报表查询,全部发到Data Guard备库(ADG)上去执行。主库负责“快”,备库负责“慢”,两者互不打扰。

这么做的好处是,报表查询再重,也最多把备库拖垮,不会影响到线上交易。同时,因为主库和备库是两套独立的实例,它们的内存、CPU进程都是分开的,资源隔离得很干净。坏处其实也很明显:数据有延迟。备库是通过同步日志来更新自己的数据,如果用异步模式,备库的数据通常会落后主库几秒甚至更长。如果业务上要求报表看到的必须是一秒钟之前的数据,那这个方案就有点为难了。

3.2 思路二:在RAC内部做“分家”

RAC不止能实现高可用,它还可以通过服务名(Service)把不同类型的应用路由到不同节点。比如说,两节点RAC,节点一专门跑OLTP应用,节点二专门跑OLAP查询。两个实例在内存上天然隔离,再配合Oracle资源管理器,限制住报表查询的CPU使用率和并行度,就能在一定程度上避免它们互相干扰。

这个玩法的最大好处是,数据完全一致,没有同步延迟。因为查询和修改都在同一个数据库里,写完立刻能读到。但缺点也躲不掉:RAC的所有节点共享同一份存储和同一个数据库。即使节点二的CPU和内存被报表打满,节点一的IO请求照样会被拖慢,因为磁盘通道是共用的。所以,这种隔离是“软隔离”,顶多算半个独立空间。

四、根据业务场景选型,记住这三条

先说结论,没有最好的架构,只有最适合你的架构。

如果你的报表查询是凌晨跑批,或者每天固定时间同步的,比如日结、月报,这种数据晚个十到二十分钟完全没关系,那就直接用“RAC主库 + ADG备库”的方案。备库晚点不要紧,只要能把查询扛下来就行。

如果你的业务是实时大屏,或者数据分析平台需要看到刚刚下单的数据,延迟必须控制在几秒内,那就不要轻易把查询放到备库,老老实实使用RAC内部服务隔离。让查询和写入都发生在主库,虽然资源紧张一点,但至少数据是实时的。

如果你的业务两样都要,既要实时,又要跑超大报表,那就把两者组合起来:主库用RAC,备库也用RAC,备库跑那些允许延迟一点的“大查询”,而主库RAC内部再做服务隔离,负责实时的小查询。这样架构会复杂很多,运维成本也会上升,但确实能最大限度照顾到不同需求。

五、部署时最容易踩的五个坑

5.1 网络抖动让备库“断奶”

Data Guard靠网络传日志,主库和备库之间的网络如果经常丢包,或者延迟忽高忽低,日志就会积压,备库数据越来越旧。很多团队为了省钱,把主备库放在同一个机柜,结果交换机一个端口松动就导致同步断半天。一定得保证主备之间的网络稳定,最好走独立的千兆甚至万兆网段。

5.2 归档日志把磁盘塞满

只要Oracle运行在归档模式下,就会不停产生归档日志。主库的归档要送到备库去应用,如果备库来不及处理,或者传输断了,备库的归档目录就会越堆越多,直到撑爆磁盘。这个坑特别常见,而且爆盘以后整库都会挂掉。建议给备库合理设置闪回恢复区的大小,并配置RMAN的归档删除策略,确保归档只保留必要的份数。

5.3 初始化参数写错,切换直接失败

很多Data Guard切换失败的案例,最后查出来都是因为初始化参数没写明白。比如log_archive_config里没有包含主备两个库的db_unique_name,或者VALID_FOR属性写得不对,导致日志在角色切换后发不出去。这些参数看似简单,但一个字母不对,切换时就会报错。

5.4 忘了监控关键指标

部署好不等于万事大吉。你得时刻盯着几个核心指标:RAC各节点负载、备库日志应用延迟、主备之间归档传输状态。建议把v$archive_dest的状态、v$standby_log中的应用进度都接入告警平台,一旦延迟超过阈值就马上通知人。

5.5 不经常做切换演练

没有演练过的Data Guard,基本等于没有。真到事故发生时再想着去切换,你会发现各种问题:密码不对、服务名不通、参数错误。所以每个季度至少要完整地做一次switchover演练,把备库升成主库,再把原主库变回备库,确保每一个环节都顺畅。

六、一套简化版配置示例(SQL*Plus技术栈)

下面的示例统一采用SQL*Plus技术栈,运行环境是Oracle 19c。我假设主库为两节点RAC,备库为单节点ADG,主库的db_unique_name是PRIM_DB,备库是STBY_DB。这里只展示最核心的命令,帮助你理解配置逻辑。

先看看主库上的RAC实例是否都健康:

-- 从全局视图查询每个RAC节点的实例状态
SELECT inst_id, instance_name, status, database_status
FROM   gv$instance
ORDER BY inst_id;

这个查询返回的结果中,正常情况下status应该是OPEN,database_status是ACTIVE。如果某一行显示MOUNTED,说明那个节点还没完全打开。

再看备库的归档接收情况,确认数据同步有没有堵住:

-- 查看归档目的地状态以及备库应用到的SCN
SELECT dest_id,
       destination,
       status,
       error,
       applied_scn-- 备库已经应用到的系统变更号
FROM   v$archive_dest
WHERE  dest_id <= 2;

status为VALID且error为空的时候,说明日志传输正常。如果你发现dest_id=2的error里有ORA错误,那就得赶紧检查网络或监听。

最后是在主库上设置DG的核心参数,让主库认识备库,并把日志以异步方式传过去:

-- 设置DG配置,必须包含主库和备库的db_unique_name
ALTER SYSTEM SET log_archive_config='DG_CONFIG=(PRIM_DB,STBY_DB)' SCOPE=BOTH;

-- 配置本地归档路径,主库和备库都需要设置
ALTER SYSTEM SET log_archive_dest_1='LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=PRIM_DB' SCOPE=BOTH;

-- 配置远程归档到备库,使用ASYNC异步传输,避免拖慢主库提交
ALTER SYSTEM SET log_archive_dest_2='SERVICE=STBY_DB ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=STBY_DB' SCOPE=BOTH;

这里面的VALID_FOR非常关键,它决定了这个归档目的地接受什么样的日志、在什么角色下生效。如果写成ONLINE_LOGFILES而数据库正好是备库角色,那日志就传不过去了。所以一定要对照主备库的实际角色来写。

有同学可能会问,配置备库怎么用命令?其实备库上也要跑类似的SQL,只是角色反过来。备库需要设置standby_file_management为AUTO,以及db_file_name_convert等与路径相关的参数。由于篇幅限制,这里不再扩展,但核心思路是主备两个方向都要配全。

七、总结

混合负载下的Oracle架构,说穿了就是一场“快”和“慢”的博弈。RAC负责把系统做厚,Data Guard负责把系统做弯,两者组合起来就能绕开很多单库扛不住的问题。但具体怎么摆,一定得回到业务身上:延迟敏感的,多在RAC内部想办法;延迟不敏感的,放心大胆地丢给ADG。无论如何,网络、归档、参数、监控和演练,这五件事一样都不能少。架构没有银弹,认清楚自己的需求,才能让Oracle跑得又稳又省心。