复制订阅知识l进阶

一:  生成快照的俩种方式: 

PS:  修改MSpublications 中的俩个参数。

@allow_anonymous = N'false' ,@immediate_sync = N'false' :当发布中添加新项目后,创建初始化快照时,快照将以增量方式创建
@allow_anonymous = N'true' ,@immediate_sync = N'true' :当发布中添加新项目后,创建初始化快照时,该发布下面所有项目的快照将全部重新初始化

如果是以增量方式创建的发布,在用脚本向发布中添加项目时,该发布相关的订阅需重新创建,即再次执行sp_addsubscription过程,否则在做快照初始化时会提示“由于没有需要初始化的订阅,因此未生成快照”。如果是以图形界面来勾选项目的话,就没这个问题,可以直接创建快照,估计这个sp_addsubscription步骤是被自动执行。

发布创建后,可以通过 sp_changepublication来变更参数

sp_changepublication @publication = 'test'
, @property = 'immediate_sync'
, @value = false
GO
sp_changepublication @publication = 'test'
, @property = 'allow_anonymous'
, @value = false
GO

 PS:  其实修改的是此表中的俩个字段信息  ---- SELECT  * FROM dbo.MSpublications s

最后,如果@allow_anonymous = N'true' ,分发库中的MSrepl_commands和MSrepl_transactions表的事务记录会保留@max_distretention 设定的时长,因为我的发布项目数量很多,所以导致这两个表的记录数相当宠大。

二: 复制订阅错误处理测试

返回给定订阅的所有事务复制错误。 此存储过程在分发服务器的分发数据库中执行:

sp_helpsubscriptionerrors [ @publisher = ] 'publisher'
[ @publisher_db = ] 'publisher_db' 
[ @publication = ] 'publication' 
[ @subscriber = ] 'subscriber' 
[ @subscriber_db = ] 'subscriber_db'

--get publisher subscriber
select * from MSsubscriber_info

--get publisher_db publication subscriber_db=publisher_db
select * from MSpublications

用于指定订阅服务器上的分发代理应用的下一个事务的日志序列号 (LSN),从而使代理可以跳过失败的事务。 此存储过程在订阅服务器上对订阅数据库执行

sp_setsubscriptionxactseqno [ @publisher= ] 'publisher'
[ @publisher_db= ] 'publisher_db'
[ @publication= ] 'publication'
[ @xact_seqno= ] xact_seqno

-使用如下语句找出错误号
select top 100 e.xact_seqno ,e.command_id,e.* 
from dbo.MSdistribution_history h
join dbo.MSrepl_errors e on h.error_id=e.id
where comments not like '%transaction%' --失败的代理
order by id desc

--用上面查到的具体事务序列号xact_seqno,查看复制的具体命令信息
--在分发数据库上执行:sp_browsereplcmds,注意必须限定开始和结束xact_seqno
sp_browsereplcmds '0x0000003B00000020000500000000','0x0000003B00000020000500000000'

三  错误排查流程

 原理: 

1)  日志读取器(LogReader)的线程通过存储过程sp_replcmdsxp_replcmds的包装)读取事务日志,它会扫描被标记为复制事务的日志,跳过非复制的事务。

2)  日志读取器的线程使用sp_MSadd_replcmds,将排队事务从读者线程写到分发数据库

3)  分发的线程执行sp_MSget_repl_commands,从分发数据库获得未处理的命令并存储到内部队列。

4)  分发的线程通过以sp_MSupdsp_MSinssp_MSdel开头的几个参数化的存储过程,将行的变更应用到订阅方的每个项目,从而将队列中的命令写到订阅服务器

5)  日志读取器和分发服务器也会执行一个历史线程,将总结数据写到分发数据库的系统表MSlogreader_historyMSdistribution_history

 

  2)如何输出出错的信息
   在待输出出错信息的JOB命令最后加入 -Output c:\temp\error.txt, -Output是命令,后面是待输出的文件路径和文件夹名.

Fetch time(ms): 3343920   <--读时间为55分钟

Write time(ms): 140070    <--写时间为3分钟

 Time to Apply Cmds (ms) : 14110  Cmds/Sec       : 3.69   <-- 写线程

Time to Retrieve Cmds (ms): 92  Cmds/Sec : 565.22      <-- 读线程

1  日志代理器读:

sp_replcmds  @maxtrans = 1    --返回下一个待完成事务的所有命令

sp_replshowcmds @maxtrans = 1        --返回从下一个待完成事务开始的所有命令及命令文本

SELECT dbid, begin_lsn, commit_lsn,rows, cmds_in_tran FROM sys.dm_repl_traninfo  

---显示最后一次被sp_replcmds或者sp_replshowcmds读取的日志中复制事务的总结信息,包括“cmds_in_tran”。值比较大可能说明有一个大型事务正在被复制。

DBCC SQLPERF (LOGSPACE)     --- Database Name , Log Size (MB), Log Space Used (%), Status
DBCC LOGINFO                        -----大量的虚拟日志文件 pub_DB

显示最后一次被sp_replcmds或者sp_replshowcmds读取的日志中复制事务的总结信息,包括“cmds_in_tran”。值比较大可能说明有一个大型事务正在被复制。

2  日志读取器写线程   sp_MSadd_replcmds的dm_exec_query_stats

--以top total_worker_time排序

SELECT TOP 25

  st.text, qp.query_plan,

    (qs.total_logical_reads/qs.execution_count) as avg_logical_reads,

    (qs.total_logical_writes/qs.execution_count) as avg_logical_writes,

    (qs.total_physical_reads/qs.execution_count) as avg_phys_reads,

  qs.*

FROM sys.dm_exec_query_stats as qs

         CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as st

         CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) as qp

WHERE st.text like 'CREATE PROCEDURE sp_MSadd_replcmds%'

  ORDER BY qs.total_worker_time DESC

------------------------------------- like 'CREATE PROCEDURE sys.sp_MSget_repl_commands%'

 分发代理器读:    -- 查看复制表的表统计信息,尤其是'Updated'(被更新)的日期

DBCC SHOW_STATISTICS(MSrepl_commands,ucMSrepl_commands)

DBCC SHOW_STATISTICS(MSrepl_transactions,ucMSrepl_transactions)

UPDATE STATISTICS MSrepl_transactions WITH FULLSCAN 

UPDATE STATISTICS MSrepl_commands   WITH FULLSCAN

 

分发代理器写:

1)是否有触发器

2) 查看所有的项目是否有SQL语句被作为批的 “参数”来发送。状态status=8说明“参数”批没有被启用。

    exec sp_addarticle @publication = ... @status = 24

   select name, status from sysarticles

 

四 、 含有Text域的数据发布问题

    BCP数据文件中遇到意外的EOF(源:ODBC SQL Server Driver(ODBC):错误代码:S1000)
    这是因为数据库中含有TEXT或nTExt或Image字段引起的,只要在某项发布属性页中选择<快照>-<快照格式>-<字符模式格式>,即可解决该问题.

   2)、对某些大型数据表无法生成快照的问题,数据库报如下错误:
        进程未能从表"[dbo].[syncobj_0x3436383044343035]"向外大容量复制,在写 BCP 数据文件时发生 I/O 错误(源: ODBC SQL Server Driver (ODBC); 错误代码: 0)
     这是因为该表有问题或表数据太大造成的,可用如下方法试着解决一下:
     a、用DBCC checktable 对该表检查一下,数据表是否有问题,然后再试一下重新生成数据快照。
     b、如果上述问题仍无法解决,可以用数据导出功能将数据表导到订阅服务器中。
     c、然后重建一个针对该数据表的数据发布,选择不生成快照功能,在发布服务器上运行如下命令:sp_scriptpublicationcustomprocs 'xxxx', 其中xxxx为发布名称,该命令会生成创建上述三个存贮过程的脚本,然后在订阅服务器运行生成三个存贮过程即可。,解决出现的问题。

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2013-03-22 17:29  莫问前程  阅读(557)  评论(0)    收藏  举报