前事不忘,后事之师,不忘国耻!

 找回密码
 用户注册
搜索
查看: 0|回复: 0

[开发应用] Oracle Redo 优化实战:从 log file sync 28ms 到组扩容与自适应同步双线收敛

[复制链接]
发表于 10 分钟前 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?用户注册

×
一、具体的问题


双十一前的压测日,订单库(Oracle 11.2.0.4 单实例 OLTP)响应时间从 80ms 抖到 600ms。AWR 报告拉出来,Top 前台等待第一位是 log file sync,平均 28.4ms,占了 31% 的 DB Time;应用侧表现就是下单慢、超时重试堆积。直觉上这是存储慢,但往下翻一行,LGWR 侧的 log file parallel write 平均只有 2.1ms——写盘明明很快,前台却等了 28ms,中间 26ms 不知去向。

再看 alert log:高峰时段每小时 20 多次 Thread 1 advanced to log sequence,也就是每 3 分钟切一次 redo;夜里还出现过几次 checkpoint not complete - cannot allocate new log。查 V$LOG,整套库只有 3 组 redo,每组 500M。三个现象拼起来:切换过频、checkpoint 卡壳、前台等待远大于写盘时间。这不是一块慢盘能解释的,得把 redo 这条链拆开看。

二、核心原理


先弄清 log file sync 到底在等什么。会话 COMMIT 时,把日志缓冲里的改动向量交给 LGWR 写盘,然后挂起等 LGWR 回执"已落盘"。判定式很简单:log file sync 的平均耗时接近 log file parallel write,说明瓶颈在存储 IO;远大于它,说明 LGWR 本身不慢,等待发生在"回执"这一段——要么切换和 checkpoint 在捣乱,要么通知机制出了问题。本例写盘 2.1ms、sync 28.4ms,是典型的不对称。

切换频率的账要算清楚。redo 组越小,切换越频繁;每次切换都会推动 checkpoint,DBWR 要把脏块刷下去,日志文件没写完新一轮检查点,新日志就分配不出来,会话集体挂在 log file sync 上等 checkpoint not complete 消失。官方文档给了粗指南:高峰期切换至多 20 分钟一次,按 20 除以当前切换间隔的倍数放大现有组;起步建议至少 3 组,且现在主流环境 redo 单组在 1G 到几个 GB 都属合理。拿不准的,直接看 V$INSTANCE_RECOVERY 的 OPTIMAL_LOGFILE_SIZE,它根据 FAST_START_MTTR_TARGET 给出建议值。

第二根线是通知机制。11.2.0.3 起,_use_adaptive_log_file_sync 默认开启,LGWR 在 post/wait 和 polling 两种回执方式间自适应:低负载用 post/wait,写完立刻点名通知;高负载切到 polling,前台睡眠轮询、不再逐个通知,省 LGWR 的 CPU。代价是高负载下前台可能多等一个轮询周期,log file sync 被莫名拉高。每次切换都记在 LGWR 的 trace 里,搜 Log file sync switching to polling 就能对上案发时间。交易型系统对这个抖动敏感,通常倾向固定 post/wait,但改隐藏参数前要先拿证据。

最后核对两个配角:redo buffer allocation retries(V$SYSSTAT)应接近 0,持续增长说明 log buffer 偏小或 checkpoint 拖后腿;user commits 每秒次数是另一面镜子,应用层逐行提交的习惯不治,存储再快也只是把 28ms 降到十几毫秒。

组数为什么也不能省?归档模式下,LGWR 写满当前组要切换到下一组,下一组必须立即可用;如果只有两组,LGWR 写满一组时 ARCH 可能还没把上一组归档完,前台会话直接挂在 log file sync 上等归档。三组起步就是为了给 ARCH 留一个周转位,归档慢的系统还要再加,这也是"扩组"和"提快归档"常常要一起做的原因。另外,FAST_START_MTTR_TARGET 定得越小,DBWR 越激进,切换时压力越大,它和 redo 组大小是一对互相牵制的参数,动一头就要回看另一头。

三、实例参考(动手步骤)


步骤 0:确认现状基线
  1. SELECT group#, thread#, sequence#, bytes/1024/1024 mb, members, status
  2.   FROM v$log ORDER BY group#;
  3. SELECT name, value FROM v$sysstat
  4. WHERE name IN ('user commits','redo buffer allocation retries');
  5. SELECT metric_name, value FROM v$sysmetric
  6. WHERE metric_name IN ('Redo Generated Per Sec','User Transaction Per Sec')
  7.    AND group_id = 2;
复制代码

本例基线:3 组×500M,user commits 约 420/秒,redo 生成约 14MB/秒,retries 已经在缓慢增长。

步骤 1:算清切换频率,定出目标组大小
  1. SELECT TO_CHAR(first_time,'YYYY-MM-DD HH24') hr, COUNT(*) switches
  2.   FROM v$archived_log
  3. WHERE first_time > SYSDATE - 14
  4. GROUP BY TO_CHAR(first_time,'YYYY-MM-DD HH24')
  5. ORDER BY 1;
复制代码

高峰时段每小时 22 次,即约 2.7 分钟一次。按官方公式放大倍数 = 20 / 2.7 ≈ 7.4,取整定 2G;再加一组做缓冲。两点提醒:一是这个 20 分钟指南是粗估,重点看业务高峰窗口的频率,凌晨跑批把全天平均拉低没有意义;二是 SQL 里用 V$ARCHIVED_LOG 统计的是已归档的切换记录,非归档模式的库改用 V$LOG_HISTORY,两者条数语义相同,一条切换一条记录。

步骤 2:加新组、删旧组(低峰窗口)
  1. ALTER DATABASE ADD LOGFILE GROUP 4
  2.   ('/u01/oradata/app/redo04a.log','/u02/oradata/app/redo04b.log') SIZE 2G;
  3. ALTER DATABASE ADD LOGFILE GROUP 5
  4.   ('/u01/oradata/app/redo05a.log','/u02/oradata/app/redo05b.log') SIZE 2G;
  5. -- 轮转后确认 V$LOG 里旧组状态非 CURRENT/ACTIVE 才能删
  6. ALTER DATABASE DROP LOGFILE GROUP 1;
复制代码

注意:CURRENT 和 ACTIVE 状态的组删不了,等轮转或手工 ALTER SYSTEM SWITCH LOGFILE 后再处理;归档模式下还要确认该组对应的归档日志已生成,否则 DROP 同样被拒。删完确认 V$LOG 和磁盘文件两头干净——DROP 命令不会自动删操作系统文件,要手工清掉,否则残留的 2G 大文件迟早把盘占满。

步骤 3:用官方建议值校准
  1. SELECT optimal_logfile_size FROM v$instance_recovery;
复制代码

返回 2048,与我们的 2G 对上,不用再追加大。

步骤 4:核对自适应同步是否在切来切去
  1. grep "Log file sync switching" $ORACLE_BASE/diag/rdbms/app/APP/trace/lgwr_*.trc
  2. SELECT name, value FROM v$sysstat
  3. WHERE name IN ('redo synch polls','redo synch poll writes');
复制代码

本例高峰时段 lgwr trace 里有 4 次 switching to polling,时间点与压测抖动完全吻合。判定时把 trace 里的切换时间戳和 AWR 快照区间对齐,能对上才有说服力;v$sysstat 里 redo synch polls 的增速也能侧面反映 polling 何时活跃。另外说明一句:12c 起 LGWR 引入日志写工作进程(SCALING 后台自动启用),单 LGWR 瓶颈的场景已缓解,polling 抖动的处置思路在 12c 上优先级会降低,本例锁定 11.2.0.4,这条线必须处理。与 Oracle Support 确认后,交易系统选择固定回执模式:
  1. ALTER SYSTEM SET "_use_adaptive_log_file_sync" = FALSE SCOPE = BOTH;
复制代码

改动前后各留一份参数快照,便于回退与审计。

步骤 5:顺手治理提交频率

和应用侧确认下单链路里逐行提交的批处理,改为每 200 行一批提交;数据库侧 retries 观察一周归零。改法不复杂:把循环体内的 COMMIT 挪到循环外,出错时按批次回滚,业务上只要接受"一批失败重跑一批"的语义就能落。存储和通知两头修完,剩下这段才轮到 log buffer 与提交习惯——顺序别颠倒,先治结构性的,再治习惯性的。

治理前后对比

指标治理前治理后
log file sync 平均28.4ms2.8ms
log file parallel write2.1ms2.0ms
redo 切换(高峰/小时)22 次3 次
checkpoint not complete17 次/周0
log file sync 占 DB Time31%4.2%
redo buffer allocation retries缓慢增长≈0
下单接口 P95612ms96ms


验证方式说明一下:表里的数据取自治理后第二个完整工作日的 AWR 快照,避开变更当天,免得把缓存预热和统计信息波动算进成绩;P95 来自应用网关的访问日志,和数据库侧指标分开取证,两边都收敛才写进结案报告。

四、实操检查清单



  • AWR 里 log file sync 与 log file parallel write 逐时段比对,差距超过 3 倍即升级排查。
  • V$ARCHIVED_LOG 按小时统计切换次数,高峰期超过每小时 3 次即触发容量复核。
  • 用 20 分钟指南算放大倍数,目标组大小经 V$INSTANCE_RECOVERY.OPTIMAL_LOGFILE_SIZE 校验。
  • redo 至少 3 组、每组至少 2 份成员且分盘放置。
  • 删旧组前核对 V$LOG 状态,CURRENT/ACTIVE 绝不动手。
  • alert log 里 checkpoint not complete 出现过即视为事故,不只记录不处置。
  • redo buffer allocation retries 每周采样,非零持续增长即立案。
  • user commits 每秒超过几百时,先和应用谈批量提交,再谈存储。
  • lgwr trace 定期搜 switching to polling,时间与业务抖动对得上再评估隐藏参数。
  • 改 _use_adaptive_log_file_sync 走变更单,留参数快照与回退步骤。
  • 扩大 redo 后重估归档量、备份窗口与 Data Guard 传输延迟。
  • 变更后跑一次完整 AWR 对比,确认占比与 P95 同步收敛才算闭环。


几个容易踩的坑



  • 只加组不改成员分布:两个成员放同一块盘,容灾等于零,坏一块盘丢一组日志。
  • SWITCH LOGFILE 强切做验证时选高峰:手工切换同样触发 checkpoint,别在业务顶点测试。
  • 把 NOLOGGING 当 redo 优化:日志少了,恢复窗口和备库数据一致性一起没了,属于把病挪到更贵的地方。
  • 只看 sync 平均值不看分布:平均值 5ms 但 P99 200ms,是 polling 抖动的典型画像,平均值会骗人。AWR 里多看一眼 Histogram 的等待时长分布,尾巴长才是问题。
  • RAC 环境照搬单实例操作:每个 thread 独立一组 redo,加组要带 THREAD 子句,逐实例算账。
  • 归档盘和 redo 放一起:切换高峰时 ARCH 与 LGWR 抢同一块盘,切换间隔反而恶化。
  • 见到 log file sync 就买存储:本例写盘 2ms,存储无罪,钱花在组扩容上才见效。
  • 隐藏参数改完不观察:改 FALSE 后 sync 若不降反升,说明调度延迟是根因,立即回退另查 CPU。
  • 扩大 redo 后忘了 checkpoint:FAST_START_MTTR_TARGET 别随手放大,实例恢复时间是拿来承诺的。
  • 死盯数据库不看应用:提交风暴是病根之一,DBA 修到 2.8ms 后,P95 能再降一半靠的是应用侧批次。
免责申明1、欢迎访问本站,本文内容及相关资源来源于网络,版权归版权方所有!本站原创内容版权归本站所有,请勿转载!
2、本文内容仅代表作者观点,不代表本站立场,作者自负,本站资源仅供学习研究,请勿非法使用,否则后果自负!请下载后24小时内删除!
3、本文内容,包括但不限于源码、文字、图片等,仅供参考。本站不对其安全性,正确性等作出保证。但本站会尽量审核会员发表的内容。
4、如本帖侵犯到任何版权问题,请立即告知本站 ,本站将及时删除并致以最深的歉意!客服邮箱:admin@dbabbs.com
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|小黑屋|DBA论坛中国 ( 鲁ICP备20017503号-2 )

GMT+8, 2026-11-11 06:01 , Processed in 0.050947 second(s), 11 queries , MemCached On.

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表