Dynamics CRM Audit Performance Troubleshooting

记一次Dynamics CRM Audit 查询失败的问题。

客户环境现象:由于业务逻辑需要使用RetrieveAuditDetailRequest API查询相关Record的详细更改信息。但查询过程中偶尔会出现失败的情况,出错原因提示是

System.TimeoutException: ‘The request channel timed out while waiting for a reply after 00:01:59.9929956. Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout.’

很明显,超时了。

那么为什么会出现超时呢?

第一感觉:会不会是因为Audit表被占用了,导致长时间等待出现超时的呢?但经过通过sp_who2排查后发现并没有block的sql。

那会不是是因为网络原因导致的呢?随后使用内网在页面上打开Record的Audit时同样失败,排除。

看一下Audit数据量有多少吧?一看,好家伙,一千多万的数据量,10多个分区表。那会不会是因为索引重建失败导致查询过慢而失败的呢?

因为Dynamics CRM默认每天都会使用Microsoft Dynamics CRM Asynchronous Processing Service (maintenance) service 执行一次p_ReindexAll的操作。

执行时间同样默认一个表会限制在2min内,详细信息见//soluciones-microsoft.blogspot.com/2018/07/how-to-improve-microsoft-dynamics-365.html

于是看一下job执行的记录,发现根本没有。怎么可能,继续看Config DB中是不是有人动过执行maintenance的schedule,

Select NextRunTime,RecurrenceStartTime,*
from MSCRM_CONFIG.dbo.ScaleGroupOrganizationMaintenanceJobs
where OperationType = 30

果真,已经被更新为不执行maintenance job了。

陷入僵局…

诶,看一下RetrieveAuditDetailRequest内部都会干些什么吧。于是本地环境使用Sql Server Profile抓了下Sql语句,嘿嘿,这货竟然会这样实现:

1、通过Audit Id将AuditBase表中的数据查询出来。

2、通过Audit 中的Object Id将Record数据查出来。

3、通过Audit 中的ChangeData将所有ChangeData中的Id每一个组成一条sql查询出来。

重点在#3,我们一个ChangeData中的Id足足有几万条诶。终于找到具体原因了,大量的sql语句导致查询时间过长而timeout。

介于时间以及整体的稳定性考虑,暂时将连接Dynamics的OrganizationServiceProxy中的Timeout Property设置为30分钟解决。

但是这么做并不能治本,因为页面上的Audit依然会有问题,这该如何解决?客户数据是万万不能删除的。如果有大神知道,麻烦评论区告知,感激~~