根本原因是rfs写srl、mrp读srl/归档并写数据文件三类i/o在同一asm磁盘组争抢,尤其stripe_column≤4时条带并行度不足导致i/o队列堆积。
根本原因不是“日志太多”,而是 rfs 进程写 srl 和 mrp 进程读 srl/归档、再写数据文件这三类 i/o 在同一 asm 磁盘组上严重争抢 —— 尤其当 stripe_column ≤ 4 时,条带并行度不足,i/o 队列立刻堆积。
为什么 RFS + MRP 会抢同一磁盘组
默认配置下,RFS 把接收到的 redo 写进 standby redo logfile(SRL),而 MRP0 从 SRL 或归档中读取并应用变更。如果 SRL、主数据文件、归档路径全落在 +DATA 这个 ASM 磁盘组里,RFS 的连续写 + MRP 的随机读 + 数据文件块更新就会在物理盘层形成串行化争用。
-
SELECT NAME, TYPE, STRIPE_COLUMN FROM V$ASM_DISKGROUP;—— 若STRIPE_COLUMN≤ 4,说明条带宽度太窄,并行写能力受限 -
SELECT GROUP#, THREAD#, SEQUENCE#, BYTES, STATUS FROM V$STANDBY_LOG;—— 检查 SRL 所在磁盘组是否和DB_CREATE_FILE_DEST相同 -
SHOW PARAMETER log_archive_dest_2—— 看LOCATION=是否也指向+DATA
如何分离 RFS 写入与 MRP 读取路径
核心动作是把 SRL 和归档强制落到独立磁盘组(如 +RECO),让 RFS 的写和 MRP 的读不碰主数据盘。
- 先停
MRP:ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL; - 加新 SRL 到
+RECO:ALTER DATABASE ADD STANDBY LOGFILE '+RECO' SIZE 2048M; - 删旧 SRL(确认状态为
UNASSIGNED或INACTIVE):ALTER DATABASE DROP STANDBY LOGFILE GROUP 4; - 改归档路径:
ALTER SYSTEM SET log_archive_dest_2='SERVICE=primary_db ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=primary_db LOCATION=+RECO' SCOPE=BOTH; - 确保
log_archive_dest_state_2=ENABLE,且standby_file_management=AUTO
SDU 设置不当会放大网络层 I/O 压力
过小的 SDU(Session Data Unit)会让 LNS/RFS 频繁拆包收发小块 redo,增加网络往返和本地 buffer copy 次数,间接抬高 CPU 和 I/O 负载。
- 查当前 SDU:
SELECT * FROM V$SESSION_CONNECT_INFO WHERE SID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = 1);,看SDU_SIZE字段 - 全局调大:
DEFAULT_SDU_SIZE=32767加到sqlnet.ora(主备两端必须一致) - 或监听器级设置:在
listener.ora的SID_DESC块里加SDU=32767
真正卡住的往往不是传输带宽,而是存储子系统对随机写(MRP 修改 datafile)的响应延迟 —— 如果 v$sysstat 里 physical reads 或 redo writes 对应的等待事件(如 db file sequential read、log file parallel write)持续超 10ms,就得优先查存储硬件和 ASM 条带配置,而不是调并行参数或加大 SGA。











