首页 > 数据库 > Oracle > 备库查不到刚提交的数据 一次 ADG 延迟排查复盘
备库查不到刚提交的数据 一次 ADG 延迟排查复盘
大家好,我是睿。
一个工作日的下午,我坐在办公桌前,刚泡好一杯茶,准备翻几页书。手机突然响了。
电话那头是某医院 HIS 运维。他说自助机业务遇到一个很奇怪的现象:主库刚录入并提交一笔数据,应用马上到 ADG 备库查询却没有结果;客户在现场连续点了几次,过了一会儿数据又出现了。
我先说明了这套环境的 同步模式 : 这套 ADG 采用 MAXIMUM PERFORMANCE 模式。在这个模式下,主库提交不会等待备库完成 redo 接收和应用,因此它本身不保证实时同步,是允许短时间延迟发生的。特别是归档日志量短时增加时, MRP 应用出现积压并不奇怪。
我把这个前提向客户解释过 了, 但客户并没有因此停止追问,他反复强调: “之前一直都是正常的,就是最近才出现这个问题,麻烦你还是帮我们查一下具体原因。”
于是我调整思路,想想 接下来要查的是:究竟是什么 原因 ,把平时很短的异步窗口放大成了业务能够感知的几秒。
现场业务是一条自助机链路。应用先在生产主库执行 INSERT 并提交,随后马上连接 ADG 备库查询刚写入的数据。故障时段里,第一次查询没有结果,等待几秒后再次查询才成功。
从业务侧看到的过程可以简化为:
主库 INSERT
主库 COMMIT 成功
应用立即 SELECT ADG 备库
第一次查询:没有结果
等待几秒
再次 SELECT :数据出现
当时能确认的只有三点:主库操作已经提交、应用查询的是 ADG 备库、数据并非缺失,而是在几秒后才变得可见。至于为什么慢,还没有答案。
最大性能模式允许延迟,但当归档量短时增加时, MRP 需要处理的 redo 也会增加。因此这次排查没有先看别的,而是先统计故障前后的归档日志生成和完成情况。
我先从 v$archived_log 和 alert 日志中按 completion_time 排序,把两个 thread 的归档记录拉出来:
select to_char(first_time,'yyyy-mm-dd hh24:mi') archive_minute,
count(*) archive_count,
round(sum(blocks * block_size) / 1024 / 1024) size_mb
from v$archived_log
where first_time >= timestamp '2026-10-28 09:00:00'
and first_time < timestamp '2026-10-28 11:00:00'
and dest_id = 1
group by to_char(first_time,'yyyy-mm-dd hh24:mi')
order by 1;
由于这是业务高峰期,归档量会比空闲时段多一些。进一步对比其他工作日同时段后,归档量整体保持稳定,暂未看到数量级暴增。因此,归档量增加是本次排查的背景条件,但还不足以单独解释这次明显的应用延迟。
接着检查主库到备库的 RFS 接收。下面这组日志中,两个 thread 的 sequence 持续递增,说明备库一直在接收新的 standby redo log :
09:58:54 RFS[56]: Selected log 35 for thread 1 sequence 345125
09:59:49 RFS[53]: Selected log 45 for thread 2 sequence 336485
10:05:07 RFS[53]: Selected log 46 for thread 2 sequence 336486
10:06:27 RFS[56]: Selected log 36 for thread 1 sequence 345126
RFS 没有完全中断,所以“日志根本没有传到备库”可以先排除。但 RFS 只负责接收,数据能不能被查询到,还要看后面的 MRP 应用。
继续在同一份 alert 日志里追踪 MRP 。这里出现了本次排查最关键的时间差:
10:05:07 Archived Log entry 64716 added for thread 2 sequence 336485
10:12:09 Media Recovery Log
/u01/oradata/archivelog/2_336485_1044746719.arc
10:12:51 Media Recovery Waiting for thread 2 sequence 336486 (in transit)
10:17:13 Archived Log entry 64719 added for thread 1 sequence 345126
10:21:46 Media Recovery Log
/u01/oradata/archivelog/1_345126_1044746719.arc
10:22:33 Media Recovery Waiting for thread 2 sequence 336487 (in transit)
thread 2 sequence 336485 在 10:05:07 完成归档, MRP 到 10:12:09 才开始读取,中间间隔约 7 分 02 秒。
thread 1 sequence 345126 的 RFS 在 10:06:27 选择下一段日志,归档条目在 10:17:13 生成, MRP 到 10:21:46 才开始读取。从 RFS 推进到 MRP 开始应用,间隔约 15 分 19 秒;从归档条目生成到 MRP 开始读取,间隔约 4 分 33 秒。
这一步把问题范围缩小到备库应用环节:归档已经生成,但 MRP 没有第一时间跟上。
MRP 应用为什么会慢?我尝试检查 MRP 进程 trace ,但该 ADG 环境没有找到对应的 trc 文件。于是我转向系统资源历史,把故障前后 09:00 到 11:00 的原始 sar 日志按十分钟粒度全部拉出来,先看底层块设备 sda :
对应采集命令如下:
sar -d -p -f /var/log/sa/sa28 -s 09:00:00 -e 11:00:00
原始磁盘指标时间序列( sda ;逻辑卷 ol_hisdg-u01 走势基本一致):
时间 iowait avgqu-sz await(ms) svctm(ms) util(%)
----------------------------------------------------------
09:00 2.42 0.20 1.45 0.95 24.74
09:10 2.62 0.19 1.36 1.01 25.70
09:20 2.36 0.18 1.41 1.01 23.47
09:30 2.16 0.14 1.27 0.95 22.96
09:40 2.41 0.14 1.22 1.00 24.10
09:50 2.39 0.30 1.91 1.01 24.14
10:00 21.62 3.51 21.48 5.37 90.05
10:10 20.03 3.22 21.41 6.40 98.48
10:20 19.66 3.19 16.90 5.01 97.36
10:30 14.15 1.99 6.68 2.38 77.77
10:40 18.01 2.68 12.30 4.05 92.24
10:50 16.15 2.21 9.73 3.39 81.48
11:00 2.49 0.17 1.35 1.07 25.07
这组数据不是单点抖动: 09:00 至 09:50 的 await 一直在 1.2 ~ 1.9 毫秒、 util 约 23% ~ 26% ; 10:00 开始 await 跳到 21.48 毫秒、 avgqu-sz 升到 3.51 、 util 达到 90.05% 。异常一直持续到 10:50 , util 仍有 81.48% ,直到 11:00 才回落到 25.07% 。 我又看了其他工作日 sar 数据,均为达到 98% 此种峰值。
为了判断是不是业务写入量突然放大,我又从同一份 sar 文件中查看了块设备吞吐:
sar -b -f /var/log/sa/sa28 -s 09:50:00 -e 11:00:00
时间 tps rtps wtps bread/s bwrtn/s
----------------------------------------------------
09:50 239.67 14.24 225.43 331.04 5472.77
10:00 167.73 14.17 153.57 280.79 4762.64
10:10 153.87 0.66 153.21 10.93 4052.11
10:20 194.47 12.62 181.85 259.09 4229.99
10:30 326.21 33.60 292.61 663.95 7261.68
10:40 227.53 17.70 209.83 347.43 4885.00
10:50 240.25 13.78 226.47 284.05 6167.05
11:00 235.00 10.94 224.06 212.34 5069.95
10:00 至 10:20 设备最忙的时候, wtps 从 225.43 降到 153.57 , bwrtn/s 也从 5472.77 降到 4052.11 ; 10:30 则出现一次明显的写请求放大。也就是说,设备响应时间和队列先恶化,写入吞吐并没有按业务流量同步增长,更符合存储侧短时响应变慢的特征。
这些现象与 MRP 应用滞后在时间上高度重合。因此,存储 I/O 响应变慢很可能是加重 MRP 积压的重要因素。
从现有证据看, 本次 ADG 库 数据 延迟 问题主要发生在 归档 应用环节:日志已经到达备库并持续完成归档,但 MRP 应用速度没有跟上。
存储 I/O 响应变慢与 MRP 滞后在时间上重合,很可能是加重应用积压的重要因素。
因此,对客户这个问题可以回答得更具体:最大性能模式决定了异步可见性始终存在,但这次业务能够明显感知到延迟,现场又同时出现了存储 I/O 恶化和 MRP 应用滞后。由于该 ADG 部署在虚拟环境上,虚拟机内部看到的 I/O 吞吐没有明显增长,但底层共享存储或宿主机资源可能受到其他工作负载影响,仍需结合虚拟化和存储侧数据确认。
处理上,支付、扣费、余额和提交后立即复核等强实时业务,建议固定访问主库。报表、历史查询和非强实时查询,可以继续由 ADG 备库承担。
同时,建议持续监控归档生成量、 RFS 接收进度、归档完成时间和 MRP 应用进度。 更高级别的保护模式主 要解决主库提交与备库收到 redo 之间的数据保护问题,并不等同于备库 MRP 已经实时完成应用;同时会提 高网络依赖和对主库性能的影响,因此不宜仅为保证查询实时一致而直接 提升保护模式 。
|
保护模式 |
日志传输方式 |
主库提交行为 |
备库不可用时 |
数据丢失风险 |
|
MAXIMUM PERFORMANCE |
通常 LGWR ASYNC NOAFFIRM |
不等待备库接收 |
主库继续运行 |
可能丢失尚未传到备库的数据 |
|
MAXIMUM AVAILABILITY |
通常 LGWR SYNC AFFIRM |
等待至少一个同步备库确认收到 redo |
主库通常继续运行,但保护级别 会 临时降级 |
同步备库正常时通常可做到零数据丢失 |
|
MAXIMUM PROTECTION |
通常 LGWR SYNC AFFIRM |
必须确认同步备库收到 redo |
无法确认时主库 会 停止 |
数据保护优先,避免主库继续产生无法保护的 redo |
点赞 + 转发 + 关注,下期我们继续分享!
—— 睿 | Oracle 性能优化老司机
专注硬核干货,欢迎一起卷技术!

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70047128/viewspace-3187395/ ,如需转载,请注明出处,否则将追究法律责任。