背景:

        一套准备上线的Oracle 11G RAC主备集群,应用报告说部分模块测试发现在备库查不到新插入的数据,而且问题发生的频率很高,需确认主备之间同步是否存在问题,此套主备之间同步采用SYNC+AFFIRM模式

问题分析:

        接到问题之后,首先分析的是主备之间的同步链路是否有问题,同步采用的是SYNC+AFFIRM模式,主库每次提交都需要确认同步日志在备库落盘之后才返回应用,所以正常主备之间同步的数据不会出现丢失,并且主备两端的存储都是NVME SSD盘,同步的时间<1秒

Oracle-DG备库应用查询不到数据问题处理-LMLPHP

        检查主库LGWR的trc文件,确认LGWR进程同步是否为sync模式或者是否出现过模式切换的情况

        从日志可以看到当前LGWR进程当前为sync模式,通过NSS2进程与备库进行日志同步,没有出现报错或者模式切换,报错的情况

Oracle-DG备库应用查询不到数据问题处理-LMLPHP

        检查NSS2进程的trc文件,进程连接备库正常,没有出现报错

Oracle-DG备库应用查询不到数据问题处理-LMLPHP

        查询备库的同步,没有看到存在传输或者应用延迟,但由于V$DATAGUARD_STATS视图只能精确到秒,无法确认是否存在<1秒的延迟

Oracle-DG备库应用查询不到数据问题处理-LMLPHP

        查看备库的历史延迟,可以看到有0秒-1秒的应用延迟出现

SELECT name, time, unit, count, TO_DATE(last_time_updated, 'MM/DD/YYYY HH24:MI:SS') 
FROM v$standby_event_histogram 
ORDER BY unit DESC, time;

        分析到这里,我们可以基本确认以下信息

        1 主备之间的链路同步没有问题,SYNC模式正常运转,每次提交日志都要在备库落盘才能完成,也就是主备之间是传输延迟不是问题的所在

        2 可能出现的瓶颈在于备库端的日志应用,因为存在<1秒的日志应用延迟,应用日志慢的可能原因,MRP进程和其并行进程的自身消耗,数据库的IO磁盘性能以及数据库的内存配置太低,这里可以暂时排除IO磁盘性能导致的问题,一方面是磁盘采用了高性能的存储,在目前备库几乎没有任何写压力的情况下,延迟<1ms,另一方面通过检查OSW基本可以排除存储存在IO等待的问题,数据库的内存配置太低也可以排除,数据库的SGA配置达到150G

        所以,接下来我们需要继续分析以下问题

        1 应用所说的部分模块测试发现在备库查不到新插入的数据,在数据库层面是否可以得到确认,因为需要定性是否是数据库层的原因或者其他方面,比如应用自身的读写中间件有问题导致

        2 数据库的MRP进程应用消耗

        接下来,我们将测试的应用同事拉过来,让他们在旁边点击该问题模块进行测试,而我们在数据库层进行查询,确认具体的执行会话以及sql,但由于执行速度太快,人为几乎无法进行跟踪,我们需要采取其他的方式进行确认

        我们首先想到的是对整个数据库开启10046,但由于生产的进程trc文件太多,对问题的分析非常的不方便,因为我们需要实时的确认应用的每一次点击,在数据库是否有查到数据

alter system set events '10046 trace name context forever,level 12'; (开启跟踪)
alter system set events '10046 trace name context off'; (关闭跟踪)

        最后,我们采用了通过查看gv$sql里面记录的sql统计信息来确认应用的每一次点击,在数据库是否有查到数据,需要注意的是由于是在备库,所以能查询的信息要比主库的少,只能通过内存里面的数据字典视图v$来获取

        通过应用提供的表名,我们在gv$sql里面捞到了具体的执行sql_id,再根据sql_id查看每次执行访问的行数ROWS_PROCESSED来确认是否查到数据

        先刷新shared pool里面的sql_id信息,再让应用点击该问题模块进行测试,这样可以更好的确认语句的执行情况

        应用测试点了两次都出现查询不到数据的问题,从数据库层查看gv$sql该语句的统计信息,语句最新执行的时间以及执行次数都匹配了应用的测试时间以及点击次数,可以发现两次执行的ROWS_PROCESSED都返回0,而在主库我们可以确认到数据已经成功插入进去,那么到这里我们可以确认该问题是在数据库层所发生的,由于备库的日志应用慢所导致

--EXECUTIONS:执行的次数
--FETCHES:结果集的返回客户端次数
--ROWS_PROCESSED:结果的返回行数
--LAST_ACTIVE_TIME:最新执行的时间
select sql_id,last_active_time,FETCHES,EXECUTIONS,ROWS_PROCESSED
from gv$sql
where upper(sql_fulltext) like '%TB_PD_JOINT_MARKETING_PROJECT%' and  sql_id='9645ubx603cdn'
order by 3

Oracle-DG备库应用查询不到数据问题处理-LMLPHP

        接下来,我们开始分析备库日志应用慢的原因,首先排除了IO磁盘性能以及数据库的内存配置所导致的,分析MRP进程和其并行进程的自身消耗

        对MRP进程设置10046进行跟踪

SQL> select process,pid from v$managed_standby where process like '%MRP%';
​
PROCESS    PID
--------- ----------
MRP0         38697
​
SQL> 
SQL> 
SQL> oradebug setospid 38697
oradebug unlimit
oradebug Event 10046 trace name context forever,level 12Oracle pid: 79, Unix process pid: 38697, image: oracle@drdb1 (MRP0)
SQL> Statement processed.

         可以看到MRP进程出现了很多'parallel recovery control message reply'并行进程通信回复的等待,很有可能是跟并行进程过多导致的通信损耗有关,当前MRP进程按照参数数量CPU_COUNT开了96个进程

Oracle-DG备库应用查询不到数据问题处理-LMLPHP

        在Oracle mos官方上也可以看到类似MRP Slow or apply lag on Active Data Guard (ADG) (Doc ID 2347080.1)的由于高并行的MRP进程导致日志应用慢的问题

Oracle-DG备库应用查询不到数据问题处理-LMLPHP

        按照官方建议的方法,采用串行的mrp日常应用或者降低mrp进程的并行度

Oracle-DG备库应用查询不到数据问题处理-LMLPHP

        调整了mrp进程的并行之后,让应用重新测试,终于可以正常查到数据,并且反复测试了几次,只要采用高并行的mrp进程复制应用就出现查询不到数据的问题

总结:

        分析下来,一方面的原因是由于备库的mrp高并行导致的日志应用慢,但另一方面,我们也需要确认这种对于备库应用延迟要求这么高(延迟要小于1秒)的业务放在备库是否合理,跟应用沟通当前的业务模块是先在主库插入数据,然后立马通过备库查询数据是否插入成功,所以才会对备库的延迟要求这么高,我想说的是,这么一个实时的业务查询放在备库其实是非常不合理的,因为主备之间同步,即使现在的网络,存储性能已经发展到很高的水平,但依然很难做到主备之间完全实时的同步,所以我们建议对于这种时间要求极高的实时查询,还是要通过主库进行访问

 

问题解决:

        1 降低MRP进程的并行度,减少并行进程过多导致的通信损耗,提高备库的日志应用速度

        2 应用层面对于这种时间要求极高的实时查询,要通过主库进行获取,不应该通过备库进行获取

 

 

 

06-26 09:30