同事讨论删除发布表历史记录,导致订阅端数据滞后N小时。后来询问得知,发布表T只保留最近31天的数据,每天由Job删除31天前的数据,每天的删除量约400-500万条。
默认情况下,在发布端删除400万条记录,这样的DEL将被作为一个大型的、多步骤事务发送到订阅服务器(有400万个命令写入到分发,并发送到订阅服务器)。
如果将删除命令封装成存储过程,并且复制存储过程的执行,则复制将仅发送在订阅服务器上执行存储过程的命令,而不会将所有DEL都写入分发数据库并随后通过网络将它们发送到订阅服务器。
问题的原因已经清晰,“如果在发布服务器上执行一个或多个存储过程并影响已发布的表,请考虑将这些存储过程作为存储过程执行项目包括在发布中。”考虑用下面步骤完成对发布的调整:
1、去掉已有发布表的DEL命令
2、将删除命令封装到存储过程,然后将对存储过程的执行添加到新发布
下面的操作是在自己电脑上测试
去掉已有发布的DEL命令
通过发布属性,去掉对其中一个表的del命令

这个界面操作后,提示标记为重新初始化(修改发布属性,就会提示初始化订阅)

实际情况我希望不标记为重新初始化,同时能不复制delete语句。
在群里请教大菠萝,他提供两种方案:
永久性:维护窗口暂停这个表的写,然后单独创建一个publication(不复制delete命令),创建不初始化的订阅,然后从之前的publication中踢掉这个表就可以了。
随时性:修改订阅端sp_MSdel_dboCounterData存储过程,把其中涉及delete的部分注释掉,改成return;这样的话,复制命令还是会走到订阅端(复制压力依然存在),但不会在订阅端应用。
永久性
环境说明:WORK\SQL12(分发服务器)、WORK\SQL08R2(发布服务器+订阅服务器),发布数据库(ReplT)、发布项目(dbo.CounterData、dbo.CounterData1)、发布名称(Table)、订阅数据库(ReplT2)
以默认的设置配置好满足上述条件的复制,接下来测试永久性操作:
创建一个发布TableNew,添加项目(表dbo.CounterData),编辑项目属性,不复制delete命令(不需立即创建快照)

创建订阅,不初始化订阅

从之前的发布中删除项目

此时可以测试,分别在从表dbo.CounterData、dbo.CounterData1删除100条数据,在订阅库下查看对应的数据,或复制监视器下查看传送命令历史记录:发布Table传递了1个事务,使用了100个命令,发布TableNew无复制的事务;同时在订阅端可以发现dbo.CounterData没有del,而dbo.CounterData1删除了100条数据。此时原发布Table不包含dbo.CounterData项目,新发布TableNew对dbo.CounterData项目不复制delete语句。
发布存储过程的执行
在发布数据库创建存储过程exec_proc,用于删除发布表dbo.CounterData的历史记录。新建发布Proc,添加项目exec_proc,编辑项目属性,复制存储过程的执行(立即创建快照)

创建订阅,初始化订阅。
上面操作完成后,发布订阅及共享文件夹情况如下:

我们在发布数据库上测试执行存储过程exec_proc,查询窗口显示,(450 行受影响);复制监视器下查看传送命令历史记录,传递了1个事务,使用了1个命令,复制仅发送在订阅服务器上执行存储过程的命令

如果我们用delete top (100) from [CounterData1]或者将此删除语句封装到存储过程执行,查询窗口显示,(100 行受影响);复制监视器下查看传送命令历史记录,传递了1个事务,使用了100个命令

因此针对发布表大批量的操作,建议复制存储过程的执行。

存储过程复制并非适用于所有应用程序。如果对某个项目进行水平筛选,以致发布服务器上存在不同于订阅服务器的行集,那么在这两个服务器上执行同一个存储过程将返回不同的结果。与此类似,如果某个更新基于另一个未复制表的子查询,那么在发布服务器和订阅服务器上同时执行相同的存储过程将返回不同的结果。

去掉已有发布表的DEL命令-随时性
通过修改订阅端sp_MSdel_dboCounterData存储过程,把其中涉及delete的部分注释掉,改成return。随时性,比较灵活,可以改来改去。如果发布端delete的操作比较频繁,对复制还是会有比较大的压力。

--修改后的del过程脚本
ALTER procedure [dbo].[sp_MSdel_dboCounterData]
@pkc1 int
as
begin
return
-- delete [dbo].[CounterData] where [id] = @pkc1 --通过主键删除
--if @@rowcount = 0 --检测是否有对应行,没有则报错
-- if @@microsoftversion>0x07320000
-- exec sp_MSreplraiserror 20598
end

对于delete操作中的检测步骤,意义不大。反正是要删除,订阅端没找到对应的行,对于当前记录来说,不会影响的实际业务需求,可以将delete中的检测语句注释。

事务复制-大批量DEL操作的更多相关文章

  1. SQL Server提高事务复制效率优化(一)总体概述

      随着公司业务的发展,数据量增长迅速,在解决Scale Out的同时,还要考虑到主从的复制延迟问题,尽量降到1s以内满足线上业务,如果不调整,SQL Server默认的配置可能平均要3s左右.生产的 ...

  2. Replication的犄角旮旯(四)--关于事务复制的监控

    <Replication的犄角旮旯>系列导读 Replication的犄角旮旯(一)--变更订阅端表名的应用场景 Replication的犄角旮旯(二)--寻找订阅端丢失的记录 Repli ...

  3. 一个事务复制的bug--更新丢失

    有两种情况会造成更新丢失,第一种是不正确的设置,例如外键或触发器的“Not For Replication” (NFR)属性没有开启.详情请参考http://blogs.msdn.com/b/apgc ...

  4. sqlserver 2005 分布式架构 对等事务复制 .

    http://www.cnblogs.com/qanholas/archive/2012/03/22/2412444.html     一.为什么要使用对等事务复制 首先要说明的是使用sqlserve ...

  5. 第五篇 Replication:事务复制-How it works

    本篇文章是SQL Server Replication系列的第五篇,详细内容请参考原文. 这一系列包含SQL Server事务复制和合并复制的详细内容,从理解基本术语和设置复制的方法,到描述它是如何工 ...

  6. 第四篇 Replication:事务复制-订阅服务器

    本篇文章是SQL Server Replication系列的第四篇,详细内容请参考原文. 订阅服务器就是复制发布项目的所有变更将传送到的服务器.每一个发布需要至少一个订阅,但是一个发布可以有多个订阅. ...

  7. 第三篇 Replication:事务复制-发布服务器

    本篇文章是SQL Server Replication系列的第三篇,详细内容请参考原文. 发布服务器是所有复制数据的源头.每一个发布服务器上可以定义多个发布.每一个发布包含一组项目(项目在同一个数据库 ...

  8. sqlserver 2000事务复制问题

    2000现在用的估计不多了,把之前收集的一些复制问题整理发布出来.可能都是些很白很二的问题,但人总是由最初的无知不断成长,不对之处欢迎指正. sqlserver 2000事务复制问题服务器A(发布) ...

  9. MySQL线上执行大事务或锁表操作

    前提 在线执行一些大事务或锁表操作(给某个核心级表加一列或者执行修改操作),此时不但主库从库要长时间锁表,主从延迟也会变大.未避免大事务sql对整个集群产生影响,,我们希望一条SQL语句只在Maste ...

随机推荐

  1. JavaScript进阶(二)

    什么是事件 JavaScript 创建动态页面.事件是可以被 JavaScript 侦测到的行为. 网页中的每个元素都可以产生某些可以触发 JavaScript 函数或程序的事件. 比如说,当用户单击 ...

  2. 升级到EF6 两个注意事项

    1.依据MSDN的官方描述: In previous versions of EF the code was split between core libraries (primarily Syste ...

  3. osg中遇到的问题

    osg中遇到的问题 今天写程序的时候, 需要把键盘和鼠标消息转发出来, 就直接写了接口用signal丢出来了. 程序写的很多, 测试的时候却崩溃了.... 在场景中拖拽鼠标左键的时候, 会发现在扔出鼠 ...

  4. 应用的启动视图 LauchView

    @interface AppDelegate () @property(strong,nonatomic) UIImageView *launchImaViewO; @property(strong, ...

  5. C#.NET Form设置/取消开机自动运行,判断程序是否已经设置成开机自动启动(转载)

    #region//开机自动运行        private void CB_Auto_CheckedChanged(object sender, EventArgs e)        {//CB_ ...

  6. IE hack中主要的几个

    _: IE6; #*+.: IE6 IE7; black\0: IE8; black\9: IE所有; @media screen\9 { … }: IE6 IE7; @media \0screen\ ...

  7. json 输出中文乱码解决办法

    echo json_decode(json_encode("修改成功")); 这样就行了

  8. C# 文件和文件夹操作

    一.文件操作 1.File类的常用静态方法: void AppendAllText(string path, string contents),将文本contents附加到文件path中 bool E ...

  9. 导入excle数据将excle数据插入到数据库

    实现功能是,用户可以直接导入对应数据,或者用户下载模板,填写数据,导入模板数据.easyui实现 前台页面 { text : '日清导入', iconCls : 'icon-print', handl ...

  10. iOS no visible @interface for 'UIButton' declares the selector errors

    no visible @interface for 'UIButton' declares the selector errors  原理不是特别理解,通过清理缓存,代码更新了,Xcode还是读旧的缓 ...