&">nbsp;
在排查
replication问题过程中,经常需要为指定的agent添加verbose log。这
首先要找到相关的作业。但在
复杂的replication环境中,一台服务器里包可能含了上百个作业,一个个去点开定义去查看简直就是噩梦。 下面的文章介绍了如何快速定位作业。所有信息都可以在Distributor 服务器里找到,以Merge replication为例子:我们发现某个订阅的上传速度很慢,接下来需要找到相应的merge agent(后面的段落中除非特别声明,否则所
有的操作都是在distributor服务器的distribution数据库内操作)1.sys.servers表,每当添加了一个publisher或subscriber之后,相应的记录都会存储在sys.servers表中,2.Msdb数据库的sysjobs表包含了所有的作业信息3.MSmerge_agents表,存储了publisher_db,publication, subscriber_sv,subscriber_name这些信息.联合3张表就可以找到相应的merge agent jobselect isnull(jobs.name,a.name) as name, a.publisher_db,a.publication as publicationName,a.subscriber_db,a.subscriber_name,s.data_source as publisherName,a.local_job From MSmerge_agents a inner join sys.servers s on a.publisher_id=s.server_idleft join msdb..sysjobs jobs on jobs.job_id=a.job_id如果是一个push模式的订阅(local_job=1),直接使用name去匹配sql server agent的作业即可(实际上msmerge_agents的name默认情况和jobs的name相同,但有可能用户意外地修改了作业名称)。如果是一个pull模式的订阅(local_job=0),就需要去subscriber
查找了。pull模式的merge agent job的命名规律:publisher-publisherDB-publicationName-subscriber-subscriberDB-serial number根据这个规律,就可以找到相应的作业了。 如果sub
端的作业也被改名了,可以通过查询msdb的sysjobsteps找到相应的command,
然后去匹配即可 (command就是replmerg.exe后面的参数,也就是在merge agent作业里的定义)select j.name ,js.command ,js.subsystem from msdb..sysjobs j inner join msdb..sysjobsteps js on j.job_id=js.job_idwhere subsystem='Merge'Snapshot agentselect jobs.name, publisher_db,publication, s.data_source as publisher,case publication_typewhen 0 then 'Transactional'when 1 then 'snapshot'when 2 then 'Merge'end as publication_typeFrom MSsnapshot_agents a inner join sys.servers s on a.publisher_id=s.server_idinner join msdb..sysjobs jobs on a.job_id=jobs.job_idjobs.name就是sql server agent job的名称命名规则:publisher-publisherDB-publicationName -serial numberLogreader agentselect jobs.name, publisher_db,s.data_source as publisherFrom MSlogreader_agents a inner join sys.servers s on a.publisher_id=s.server_idinner join msdb..sysjobs jobs on a.job_id=jobs.job_idjobs.name就是sql server agent job的名称(
同一个数据库的多个publication共用一个Logreader agent)Distribution agentselect isnull(jobs.name,a.name) as name, a.publisher_db,a.publication as publicationName,s.name as publisherName ,s.data_source as publisherName,s1.data_source as subscriber,a.subscriber_db, a.local_job From MSdistribution_agents a inner join sys.servers s on a.publisher_id=s.server_idinner join sys.servers s1 on a.subscriber_id =s1.server_idleft join msdb..sysjobs jobs on a.job_id=jobs.job_idwhere a.subscription_type <>2--- filter out the anonymous subscriber如果是一个push模式的订阅(local_job=1),直接用name匹配即可。如果是一个pull模式的订阅(local_job=0),就比较麻烦了,因为作业名称没有什么规律可言。下面是一个subscriber端job的截图我们需要查询subscriber的subscription database.其中的distribution agent列直接匹配作业的名称(如果作业名称被修改,则需要查询sysjobs)。select job.name ,s.distribution_agent from msdb..sysjobs job inner join MSreplication_subscriptions s on job.job_id=s.agent_id如何找到replication运行时执行的语句8630.html">有时候在解决复杂的replication问题时,我们需要捕获sql server trace,查找其中的原因。但在实际的生产环境中,sqlserver会同时处理
大量的语句,大量的非相关的sql语句会干扰我们排查问题。假设一台订阅器上有多个mergeagent在同时运行,那我们如何从trace里找出我们需要的信息呢?1.抓取publisher, distributor 和 subscriber三台服务器的trace2.在distribution数据库里查询(不区分pull还是push):a)select name,* From MSmerge_agents3.在这里得到了merge agent的名称,用ApplicationName去过滤publisher的端收集到的trace,得到clientProcessID,用这个clientProcessID就可以得到merge agent发出的所有语句了。再用这个clientProcessID,可以找到在distributor和subscriber端发出的语句。(每个merge agent都会有单独的ProcessID,所有用这个processID就可以找到同一个merge agent在publisher, distributor和subscriber发出的语句了)处理distribution agent也很类似,只需要将第二步的MSmerge_agents替换成MSdistribution_agents即可。用name去过滤distributor的trace,得到clientProcessid,根据这个clientProcessid,到sub进行过滤。Logreaderagent的applicationName的命名规则就比较特殊了,为Repl-LogReader-number-publicationDBName-number,用这个去匹配publisher和distributor上的trace内容即可。