当复制有延迟时,我们可以使用复制监视器来查看各订阅的未分发命令书和预估所需时间,如下图:

但是当分发和订阅数比较多的时候,依次查看比较费时,我们可以使用sys.sp_replmonitorsubscriptionpendingcmds来查看,但是该命令需要输入多个参数,也比较累人,后从菠萝兄哪找寻得一个脚本,对该命令进行了一次封装:

  1. --在分发服务器执行
  2. USE distribution
  3.  
  4. SELECT 'EXEC distribution.sys.sp_replmonitorsubscriptionpendingcmds @publisher = N'''
  5. + a.publisher + ''', @publisher_db = N''' + a.publisher_db
  6. + ''', @publication = N''' + a.publication + ''', @subscriber = N'''
  7. + c.name + ''', @subscriber_db = N''' + b.subscriber_db
  8. + ''', @subscription_type =' + CAST(b.subscription_type AS VARCHAR)
  9. FROM dbo.MSreplication_monitordata a ( NOLOCK )
  10. JOIN ( SELECT publication_id ,
  11. subscriber_id ,
  12. subscriber_db ,
  13. subscription_type
  14. FROM MSsubscriptions (NOLOCK)
  15. GROUP BY publication_id ,
  16. subscriber_id ,
  17. subscriber_db ,
  18. subscription_type
  19. ) b ON a.publication_id = b.publication_id
  20. JOIN sys.servers c ( NOLOCK ) ON b.subscriber_id = c.server_id
  21. WHERE a.agent_type = 1

执行该脚本,可以生成相应命令,再依次执行命令可以获取我们想要的结果。

为方便查看,我在菠萝的脚本上做了改进,以便可以更方便查看:

  1. --查看为传递到订阅的命令和预估时间
  2. --在分发服务器执行
  3. IF(OBJECT_ID('tempdb..#tmpSubscribers') IS NOT NULL)
  4. BEGIN
  5. DROP TABLE #tmpSubscribers
  6. END
  7. GO
  8. --IF(OBJECT_ID('tempdb..#tmpPendingResult') IS NOT NULL)
  9. --BEGIN
  10. --DROP TABLE #tmpPendingResult
  11. --END
  12.  
  13. --GO
  14. --IF(OBJECT_ID('tempdb..#tmpSinglePendingResult') IS NOT NULL)
  15. --BEGIN
  16. --DROP TABLE #tmpSinglePendingResult
  17. --END
  18. GO
  19. USE distribution
  20. GO
  21. SELECT
  22. a.publisher
  23. ,a.publisher_db
  24. ,a.publication
  25. ,c.name as subscriber
  26. ,b.subscriber_db as subscriber_db
  27. ,CAST(b.subscription_type AS VARCHAR) as subscription_type
  28. ,'EXEC distribution.sys.sp_replmonitorsubscriptionpendingcmds @publisher = N'''
  29. + a.publisher + ''', @publisher_db = N''' + a.publisher_db
  30. + ''', @publication = N''' + a.publication + ''', @subscriber = N'''
  31. + c.name + ''', @subscriber_db = N''' + b.subscriber_db
  32. + ''', @subscription_type =' + CAST(b.subscription_type AS VARCHAR) AS ScriptTxt
  33. INTO #tmpSubscribers
  34. FROM dbo.MSreplication_monitordata a ( NOLOCK )
  35. JOIN ( SELECT publication_id ,
  36. subscriber_id ,
  37. subscriber_db ,
  38. subscription_type
  39. FROM MSsubscriptions (NOLOCK)
  40. GROUP BY publication_id ,
  41. subscriber_id ,
  42. subscriber_db ,
  43. subscription_type
  44. ) b ON a.publication_id = b.publication_id
  45. JOIN sys.servers c ( NOLOCK ) ON b.subscriber_id = c.server_id
  46. WHERE a.agent_type = 1
  47. --====================================================
  48. --CREATE TABLE #tmpPendingResult
  49. --(
  50. --publisher NVARCHAR(200)
  51. --,publisher_db NVARCHAR(200)
  52. --,publication NVARCHAR(200)
  53. --,subscriber NVARCHAR(200)
  54. --,subscriber_db NVARCHAR(200)
  55. --,subscription_type NVARCHAR(200)
  56. --,pendingcmdcount BIGINT
  57. --,estimatedprocesstime BIGINT
  58. --)
  59.  
  60. --CREATE TABLE #tmpSinglePendingResult
  61. --(
  62. --pendingcmdcount BIGINT
  63. --,estimatedprocesstime BIGINT
  64. --)
  65.  
  66. --==================================================
  67. --使用游标遍历
  68. DECLARE @publisher NVARCHAR(200);;
  69. DECLARE @publisher_db NVARCHAR(200);
  70. DECLARE @publication NVARCHAR(200);
  71.  
  72. DECLARE @subscriber NVARCHAR(200);;
  73. DECLARE @subscriber_db NVARCHAR(200);
  74. DECLARE @subscription_type NVARCHAR(200);
  75. DECLARE @ScriptTxt NVARCHAR(MAX);
  76.  
  77. DECLARE MyCursor CURSOR FOR
  78. SELECT publisher
  79. ,publisher_db
  80. ,publication
  81. ,subscriber
  82. ,subscriber_db
  83. ,subscription_type
  84. ,ScriptTxt
  85. FROM #tmpSubscribers;
  86.  
  87. OPEN MyCursor
  88.  
  89. FETCH NEXT FROM MyCursor
  90. INTO @publisher
  91. ,@publisher_db
  92. ,@publication
  93. ,@subscriber
  94. ,@subscriber_db
  95. ,@subscription_type
  96. ,@ScriptTxt;
  97.  
  98. WHILE @@FETCH_STATUS = 0
  99. BEGIN
  100. SELECT
  101. @publisher AS publisher
  102. ,@publisher_db AS publisher_db
  103. ,@publication AS publication
  104. ,@subscriber AS subscriber
  105. ,@subscriber_db AS subscriber_db
  106. ,@subscription_type AS subscription_type
  107. ,@ScriptTxt;
  108.  
  109. EXEC(@ScriptTxt)
  110.  
  111. FETCH NEXT FROM MyCursor
  112. INTO @publisher
  113. ,@publisher_db
  114. ,@publication
  115. ,@subscriber
  116. ,@subscriber_db
  117. ,@subscription_type
  118. ,@ScriptTxt;
  119.  
  120. END
  121.  
  122. CLOSE MyCursor
  123. DEALLOCATE MyCursor

由于使用sp_replmonitorsubscriptionpendingcmds,无法将存储过程的结果插入到一个临时表中查看,因此想到参考其存储过程,编写一个类似脚本,于是有了下面脚本:

  1. USE distribution
  2. go
  3. IF ( OBJECT_ID('dbo.sp_replmonitorsubscriptionpendingcmds_EX ') IS NOT NULL )
  4. BEGIN
  5. DROP PROCEDURE dbo.sp_replmonitorsubscriptionpendingcmds_EX
  6. END
  7. GO
  8. CREATE PROCEDURE dbo.sp_replmonitorsubscriptionpendingcmds_EX
  9. AS
  10. BEGIN
  11. SET nocount ON
  12. CREATE TABLE #tmpPendingResult
  13. (
  14. publisher NVARCHAR(200) ,
  15. publisher_db NVARCHAR(200) ,
  16. publication NVARCHAR(200) ,
  17. subscriber NVARCHAR(200) ,
  18. subscriber_db NVARCHAR(200) ,
  19. subscription_type NVARCHAR(200) ,
  20. pendingcmdcount BIGINT ,
  21. estimatedprocesstime BIGINT
  22. )
  23.  
  24. --查找所有订阅
  25. SELECT a.publisher ,
  26. a.publisher_db ,
  27. a.publication ,
  28. c.name AS subscriber ,
  29. b.subscriber_db AS subscriber_db ,
  30. CAST(b.subscription_type AS VARCHAR) AS subscription_type
  31. INTO #tmpSubscribers
  32. FROM dbo.MSreplication_monitordata a ( NOLOCK )
  33. JOIN ( SELECT publication_id ,
  34. subscriber_id ,
  35. subscriber_db ,
  36. subscription_type
  37. FROM MSsubscriptions (NOLOCK)
  38. GROUP BY publication_id ,
  39. subscriber_id ,
  40. subscriber_db ,
  41. subscription_type
  42. ) b ON a.publication_id = b.publication_id
  43. JOIN sys.servers c ( NOLOCK ) ON b.subscriber_id = c.server_id
  44. WHERE a.agent_type = 1
  45.  
  46. DECLARE @count INT
  47. SELECT @count = COUNT(1)
  48. FROM #tmpSubscribers
  49.  
  50. PRINT 'Subscriber Counter:' + CAST(@count AS VARCHAR(200));
  51.  
  52. DECLARE @publisher NVARCHAR(200);;
  53. DECLARE @publisher_db NVARCHAR(200);
  54. DECLARE @publication NVARCHAR(200);
  55.  
  56. DECLARE @subscriber NVARCHAR(200);;
  57. DECLARE @subscriber_db NVARCHAR(200);
  58. DECLARE @subscription_type NVARCHAR(200);
  59.  
  60. DECLARE MyCursor CURSOR
  61. FOR
  62. SELECT publisher ,
  63. publisher_db ,
  64. publication ,
  65. subscriber ,
  66. subscriber_db ,
  67. subscription_type
  68. FROM #tmpSubscribers;
  69. OPEN MyCursor
  70.  
  71. FETCH NEXT FROM MyCursor
  72. INTO @publisher, @publisher_db, @publication, @subscriber, @subscriber_db,
  73. @subscription_type;
  74.  
  75. DECLARE @Error NVARCHAR(MAX)
  76. WHILE @@FETCH_STATUS = 0
  77. BEGIN
  78.  
  79. SELECT @Error = '@publisher=' + @publisher
  80. + ';@publisher_db=' + @publisher_db + ';@publication='
  81. + @publication + ';@subscriber=' + @subscriber
  82. + ';@subscriber_db' + @subscriber_db
  83.  
  84. PRINT '开始:' + @Error;
  85.  
  86. DECLARE @retcode INT ,
  87. @agent_id INT ,
  88. @publisher_id INT ,
  89. @subscriber_id INT ,
  90. @lastrunts TIMESTAMP ,
  91. @avg_rate FLOAT ,
  92. @xact_seqno VARBINARY(16) ,
  93. @inactive INT = 1 ,
  94. @virtual INT = -1
  95.  
  96. --
  97. -- PAL security check done inside sp_MSget_repl_commands
  98. -- security: Has to be executed from distribution database
  99. --
  100. -- if sys.fn_MSrepl_isdistdb (db_name()) != 1
  101. -- begin
  102. -- --raiserror (21482, 16, -1, 'sp_replmonitorsubscriptionpendingcmds', 'distribution')
  103. -- --return 1
  104. --SELECT @Error='@publisher='+@publisher+';@publisher_db='+@publisher_db
  105. --+';@publication='+@publication+';@subscriber='+@subscriber+';@subscriber_db'+@subscriber_db
  106.  
  107. --PRINT @Error
  108.  
  109. --CONTINUE;
  110. -- end
  111. --
  112. -- validate @subscription_type
  113. --
  114. IF ( @subscription_type NOT IN ( 0, 1 ) )
  115. BEGIN
  116. --raiserror(14200, 16, 3, '@subscription_type')
  117. --return 1
  118.  
  119. PRINT 'ERROR IN subscription_type'
  120.  
  121. CONTINUE;
  122. END
  123. --
  124. -- get the server ids for publisher and subscriber
  125. --
  126. SELECT @publisher_id = server_id
  127. FROM sys.servers
  128. WHERE UPPER(name) = UPPER(@publisher)
  129. IF ( @publisher_id IS NULL )
  130. BEGIN
  131. --raiserror(21618, 16, -1, @publisher)
  132. --return 1
  133.  
  134. PRINT 'ERROR IN publisher_id'
  135.  
  136. CONTINUE;
  137. END
  138. SELECT @subscriber_id = server_id
  139. FROM sys.servers
  140. WHERE UPPER(name) = UPPER(@subscriber)
  141. IF ( @subscriber_id IS NULL )
  142. BEGIN
  143. --raiserror(20032, 16, -1, @subscriber, @publisher)
  144. --return 1
  145.  
  146. PRINT 'ERROR IN subscriber_id'
  147.  
  148. CONTINUE;
  149. END
  150. --
  151. -- get the agent id
  152. --
  153. SELECT @agent_id = id
  154. FROM dbo.MSdistribution_agents
  155. WHERE publisher_id = @publisher_id
  156. AND publisher_db = @publisher_db
  157. AND publication IN ( @publication, 'ALL' )
  158. AND subscriber_id = @subscriber_id
  159. AND subscriber_db = @subscriber_db
  160. AND subscription_type = @subscription_type
  161. IF ( @agent_id IS NULL )
  162. BEGIN
  163. --raiserror(14055, 16, -1)
  164. --return (1)
  165.  
  166. PRINT 'ERROR IN agent_id'
  167.  
  168. CONTINUE;
  169. END;
  170. --
  171. -- Compute timestamp for latest run
  172. --
  173. WITH dist_sessions ( start_time, runstatus, timestamp )
  174. AS ( SELECT start_time ,
  175. MAX(runstatus) ,
  176. MAX(timestamp)
  177. FROM dbo.MSdistribution_history
  178. WHERE agent_id = @agent_id
  179. AND runstatus IN ( 2, 3, 4 )
  180. GROUP BY start_time
  181. )
  182. SELECT @lastrunts = MAX(timestamp)
  183. FROM dist_sessions;
  184. IF ( @lastrunts IS NULL )
  185. BEGIN
  186. --
  187. -- Distribution agent has not run successfully even once
  188. -- and virtual subscription of immediate sync publication is inactive (snapshot has not run), no point of returning any counts
  189. -- see SQLBU#320752, orig fix SD#881433, and regression bug VSTS# 140179 before you attempt to fix it differently :)
  190. IF EXISTS ( SELECT *
  191. FROM dbo.MSpublications p
  192. JOIN dbo.MSsubscriptions s ON p.publication_id = s.publication_id
  193. WHERE p.publisher_id = @publisher_id
  194. AND p.publisher_db = @publisher_db
  195. AND p.publication = @publication
  196. AND p.immediate_sync = 1
  197. AND s.status = @inactive
  198. AND s.subscriber_id = @virtual )
  199. BEGIN
  200. -- select 'pendingcmdcount' = 0, N'estimatedprocesstime' = 0
  201. --return 0
  202. INSERT INTO #tmpPendingResult
  203. ( publisher ,
  204. publisher_db ,
  205. publication ,
  206. subscriber ,
  207. subscriber_db ,
  208. subscription_type ,
  209. pendingcmdcount ,
  210. estimatedprocesstime
  211. )
  212. SELECT @publisher ,
  213. @publisher_db ,
  214. @publication ,
  215. @subscriber ,
  216. @subscriber_db ,
  217. @subscription_type ,
  218. 0 ,
  219. 0
  220.  
  221. END
  222. --
  223. -- Grab the max timestamp
  224. --
  225. SELECT @lastrunts = MAX(timestamp)
  226. FROM dbo.MSdistribution_history
  227. WHERE agent_id = @agent_id
  228. END
  229. --
  230. -- get delivery rate for the latest completed run
  231. -- get the latest sequence number
  232. --
  233. SELECT @xact_seqno = xact_seqno ,
  234. @avg_rate = delivery_rate
  235. FROM dbo.MSdistribution_history
  236. WHERE agent_id = @agent_id
  237. AND timestamp = @lastrunts
  238. --
  239. -- if no rows are selected in last query
  240. -- explicitly initialize these variables
  241. --
  242. SELECT @xact_seqno = ISNULL(@xact_seqno, 0x0) ,
  243. @avg_rate = ISNULL(@avg_rate, 0.0)
  244. --
  245. -- if we do not have completed run
  246. -- get the average for the agent in all runs
  247. --
  248. IF ( @avg_rate = 0.0 )
  249. BEGIN
  250. SELECT @avg_rate = ISNULL(AVG(delivery_rate), 0.0)
  251. FROM dbo.MSdistribution_history
  252. WHERE agent_id = @agent_id
  253. END
  254. --
  255. -- get the count of undelivered commands
  256. -- PAL check done inside
  257. --
  258. DECLARE @countab TABLE ( pendingcmdcount INT )
  259. INSERT INTO @countab
  260. ( pendingcmdcount
  261. )
  262. EXEC @retcode = sys.sp_MSget_repl_commands @agent_id = @agent_id,
  263. @last_xact_seqno = @xact_seqno, @get_count = 2,
  264. @compatibility_level = 9000000
  265. IF ( @retcode != 0
  266. OR @@error != 0
  267. )
  268. --return 1
  269. CONTINUE;
  270. --
  271. -- compute the time to process
  272. -- return the resultset
  273. --
  274. INSERT INTO #tmpPendingResult
  275. ( publisher ,
  276. publisher_db ,
  277. publication ,
  278. subscriber ,
  279. subscriber_db ,
  280. subscription_type ,
  281. pendingcmdcount ,
  282. estimatedprocesstime
  283. )
  284. SELECT @publisher ,
  285. @publisher_db ,
  286. @publication ,
  287. @subscriber ,
  288. @subscriber_db ,
  289. @subscription_type ,
  290. pendingcmdcount ,
  291. CASE WHEN ( @avg_rate != 0.0 )
  292. THEN CAST(( CAST(pendingcmdcount AS FLOAT)
  293. / @avg_rate ) AS INT)
  294. ELSE pendingcmdcount
  295. END
  296. FROM @countab
  297. --
  298. -- all done
  299. --
  300. --CONTINUE;
  301.  
  302. FETCH NEXT FROM MyCursor
  303. INTO @publisher, @publisher_db, @publication, @subscriber, @subscriber_db,
  304. @subscription_type;
  305.  
  306. END
  307.  
  308. CLOSE MyCursor
  309. DEALLOCATE MyCursor
  310.  
  311. SELECT *
  312. FROM #tmpPendingResult
  313.  
  314. END
  315. GO
  316. --=========================================================
  317. --测试
  318. EXEC dbo.sp_replmonitorsubscriptionpendingcmds_EX

上面相对使用起来更方便些。哈哈

--============================================================================================

来个妹子给大家降降温

Replication--查看未分发命令和预估所需时间的更多相关文章

  1. SqlServer 监控发布中未分发的命令数

    原文:SqlServer 监控发布中未分发的命令数 对于查看未分发的命令数,我们通常这样查看. 然而当服务器有很多发布时,一个个打开查看就很麻烦 当然,如果想用脚本查看就更方便了,运行下面的语句 -- ...

  2. LINUX查看硬件配置命令

    LINUX查看硬件配置命令   系统 # uname -a # 查看内核/操作系统/CPU信息 # head -n 1 /etc/issue # 查看操作系统版本 # cat /proc/cpuinf ...

  3. Linux下查看进程的命令输出的内容解释

    Linux下查看进程的命令输出的内容解释 ps (process status) ps -e 或者ps -A (-e和-A完全一样) PID           TTY         TIME   ...

  4. CentOS Linux 7 提示 lsof: 未找到命令

    我们常使用 lsof -i:端口号 命令来查看某端口是否开放,如使用下面的命令,查看8080端口: lsof -i: 结果: 提示:lsof:未找到命令 解决办法 使用yum来安装lsof,命令如下: ...

  5. SQLServer 使用sp_repldone标识所有未分发的事务为已分发

    原文:SQLServer 使用sp_repldone标识所有未分发的事务为已分发 对于发布数据库的数据大量操作时,会使日志扫描并读取太多,会导致分发堵塞很久.也有一些解决方法,参考 <SqlSe ...

  6. Ubuntu系统---又显示nvidia-smi 未找到命令

    Ubuntu系统---又显示nvidia-smi 未找到命令 本来nvidia驱动+CUDA安装好用,两次遇到开机发现字体异常,不用合计,是显卡驱动的问题.一查,确实是nvidia-smi 未找到命令 ...

  7. linux -bash: unzip: 未找到命令(实测有效!)

    今天使用linux解压的时候遇到了不能解压的问题,然后就看了一些文档,写一个解决方案 Linux version 3.10.0-957.10.1.el7.x86_64 (mockbuild@kbuil ...

  8. Fedora javac 命令提示 [javac: 未找到命令...]

    [joy@localhost ~]$ java -version openjdk version "1.8.0_91" OpenJDK Runtime Environment (b ...

  9. Linux查看系统状态命令

    Linux查看系统状态命令       iostat iostat 命令详细地显示了存储子系统方面的情况.你通常用iostat来监控存储子系统总体上运行状况如何,并且在用户注意到服务器运行缓慢之前提早 ...

随机推荐

  1. IDEA 工具下导出文件及文件的目录结构插件

    idea导出增量补丁插件 有时候需要导出IDEA的文件目录结构,即导出  指定修改后的JAVA文件编译后的CLASS .或者是修改过的jsp.配置文件等, 装载此插件,即可以完成导出文件  及文件的目 ...

  2. Django配置Bootstrap, js

    1.首先在APP目录下创建一个static文件夹 如图: # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'dj ...

  3. laravel在控制器中赋值给视图

    1.控制器 2.视图

  4. oracle 新建数据库 ,新建用户

    net manager   数据库名----电脑名localhost 1521  , 服务名  orcl (oracle 版本不一样, 不同版本不一样,,)  然后测试.. sys 账号登录  新建用 ...

  5. MySQL之练习题5

    .将所有的课程的名称以及对应的任课老师姓名打印出来,如下: SELECT cname,tname FROM course INNER JOIN teacher WHERE course.teacher ...

  6. 645. Set Mismatch

    static int wing=[]() { std::ios::sync_with_stdio(false); cin.tie(NULL); ; }(); class Solution { publ ...

  7. 2018.08.28 洛谷P4360 [CEOI2004]锯木厂选址(斜率优化dp)

    传送门 一道斜率优化dp入门题. 是这样的没错... 我们用dis[i]表示i到第三个锯木厂的距离,sum[i]表示前i棵树的总重量,w[i]为第i棵树的重量,于是发现如果令第一个锯木厂地址为i,第二 ...

  8. Django入门与实践-第17章:保护视图(完结)

    http://127.0.0.1:8000/boards/1/ #boards/views.py from django.contrib.auth.decorators import login_re ...

  9. Axios的基本使用

    Axios的基本使用 介绍 Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中.在vue 中,用来发ajax请求,与后端交互. 从浏览器中创建 XMLHtt ...

  10. mysql报错排查总结

    mysql报错: [root@zabbix ~]# mysql ERROR 2002 (HY000): Can't connect to local MySQL server through sock ...