天天看点

SQL Server 事务复制分发到订阅同步慢

最近发现有一个发布经常出现问题,每几天就出错不同步,提示要求初始化。重新调整同步后,复制还是很慢!每天白天未分发的命令就达五六百万条!要解决慢的问题,需要了解从发布数据库到订阅数据库中,有哪些操作,才知道哪个步骤同步缓慢。

这是很久之前自己做的一张图,主要描述发布到分发、分发到订阅中,复制使用了哪些操作,如下图:

SQL Server 事务复制分发到订阅同步慢

发布到分发:

在发布中,复制是使用日志读取器读(sp_replcmds)取发布数据库中的事务日志的,日志读取器是按事务顺序读取的,所以每个数据库只能有一个(若有CDC也使用同一个日志读取器)。

首选,在事务日志中,到底有多少是需要复制的?使用以下命令,可以确定事务日志中被标志为复制的命令有多少。

如果事务日志中标志为复制的命令很多,常见的种情况有:

1. 有一个较大的事务还没读取到;

2. 日志读取器出现问题;

正常来说,日志读取器扫描日志还是比较快的,不会有什么问题,不会累计较多待读取的日志。可以使用性能计数器监控日志读取器读取情况:

"\SQLServer:Replication Logreader\Logreader:Delivered Cmds/sec"

"\SQLServer:Replication Logreader\Logreader:Delivered Trans/sec"

日期读取器读取事务日志后,会通过存储过程 sp_msadd_commands 写入到分发服务器上的分发数据库  distribution 。但是写入是否正常呢?从上面计数器跟踪的情况,可以估计每分钟有读取了多少命令。需要分发的事务和命令,系统存储过程分别写入了分发库上的表 MSrepl_transactions和 MSrepl_commands

,这两个表记录了需要分发的命令(注意:其中的命令可能已经分发到订阅了,只是还没清除)。将两表关联按分钟统计,可以确定每分钟写入到分发库上的命令有多少了。

在发布到分发中,事务命令的读取和写入可做对比,确定读或写是哪段出现问题。

分发到订阅:

分发到订阅,首选确定有多少命令是需要分发的,若直接求和  MSrepl_transactions 和 MSrepl_commands是不准确的,因为有的已经分发了。可以打开复制监视器查看某个发布中未分发的命令,若用脚本查看,有两个方法:

总体监控分发到订阅的情况,可以使用计数器跟踪:

"\SQLServer:Replication Dist\Dist:Delivered Cmds/sec"

"\SQLServer:Replication Dist\Dist:Delivered Trans/sec"

若了解更详细情况,可在分发代理中添加以下参数,重启分发作业。

-Output [output_path_and_file_name]

-OutputVerboseLevel [0|1|2]]

接下来回归主题:SQL Server 事务复制分发到订阅同步慢

当前未分发的命令已经堵了六百多万条了,而分发差不多两分钟才分发一次。在分发数据库中查看当前执行了什么命令,经常看到在执行存储过程

sp_MSget_repl_commands ,该存储过程是从  MSrepl_transactions 和 MSrepl_commands 读取未分发的命令,将这些命令应用到订阅中。但是读取出现了等待类型ASYNC_NETWORK_IO

,ASYNC_NETWORK_IO  意思是数据已经读取了,但是客户的还没有完全把数据拿走。按正常理解,这些这个等待类型,很可能是网络问题。

SQL Server 事务复制分发到订阅同步慢

为了确定是不是网络问题,我用了以下方法:

1.  从其他不堵塞的发布中,插入跟踪器。确认整个过程网络没什么问题。

SQL Server 事务复制分发到订阅同步慢

2. ping 网络,看时间多少。基本1ms 内,正常!

3. 订阅中创建一个共享文件夹,在分发服务器访问共享,拷贝一个大文件过去。拷贝速度66mb/s ,没毛病!

既然网络没什么问题,那就要确定是不是分发到订阅中 “写” 出现了问题?到订阅服务器查看当前执行了什么命令,发现一个命令总数一直在执行!

SQL Server 事务复制分发到订阅同步慢

从缓存中,查看执行情况,发现该存储过程耗时非常多!

点击上面查询出来的执行计划,发现应用的表竟然用表扫描!!!

SQL Server 事务复制分发到订阅同步慢

找到表 MDS_ADRelation ,发现竟然没有主键(或索引)!!

表发布订阅是必须有主键的,订阅也会一会保留主键的,数据的同步更新就是按主键做条件进行更新的,而表主键没了,更新就用不上索引了!!真不知道是谁删除的!

从发布中把创建主键的脚本导出来,到订阅执行,因为同步正在进行,创建主键时使用 (online=on)在线创建。创建完成后,分发瞬间加快(如下图),订阅中流量也瞬间加大了!!复制终于正常了!!

SQL Server 事务复制分发到订阅同步慢