事务复制-大批量DEL操作
同事讨论删除发布表历史记录,导致订阅端数据滞后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操作的更多相关文章
- SQL Server提高事务复制效率优化(一)总体概述
随着公司业务的发展,数据量增长迅速,在解决Scale Out的同时,还要考虑到主从的复制延迟问题,尽量降到1s以内满足线上业务,如果不调整,SQL Server默认的配置可能平均要3s左右.生产的 ...
- Replication的犄角旮旯(四)--关于事务复制的监控
<Replication的犄角旮旯>系列导读 Replication的犄角旮旯(一)--变更订阅端表名的应用场景 Replication的犄角旮旯(二)--寻找订阅端丢失的记录 Repli ...
- 一个事务复制的bug--更新丢失
有两种情况会造成更新丢失,第一种是不正确的设置,例如外键或触发器的“Not For Replication” (NFR)属性没有开启.详情请参考http://blogs.msdn.com/b/apgc ...
- sqlserver 2005 分布式架构 对等事务复制 .
http://www.cnblogs.com/qanholas/archive/2012/03/22/2412444.html 一.为什么要使用对等事务复制 首先要说明的是使用sqlserve ...
- 第五篇 Replication:事务复制-How it works
本篇文章是SQL Server Replication系列的第五篇,详细内容请参考原文. 这一系列包含SQL Server事务复制和合并复制的详细内容,从理解基本术语和设置复制的方法,到描述它是如何工 ...
- 第四篇 Replication:事务复制-订阅服务器
本篇文章是SQL Server Replication系列的第四篇,详细内容请参考原文. 订阅服务器就是复制发布项目的所有变更将传送到的服务器.每一个发布需要至少一个订阅,但是一个发布可以有多个订阅. ...
- 第三篇 Replication:事务复制-发布服务器
本篇文章是SQL Server Replication系列的第三篇,详细内容请参考原文. 发布服务器是所有复制数据的源头.每一个发布服务器上可以定义多个发布.每一个发布包含一组项目(项目在同一个数据库 ...
- sqlserver 2000事务复制问题
2000现在用的估计不多了,把之前收集的一些复制问题整理发布出来.可能都是些很白很二的问题,但人总是由最初的无知不断成长,不对之处欢迎指正. sqlserver 2000事务复制问题服务器A(发布) ...
- MySQL线上执行大事务或锁表操作
前提 在线执行一些大事务或锁表操作(给某个核心级表加一列或者执行修改操作),此时不但主库从库要长时间锁表,主从延迟也会变大.未避免大事务sql对整个集群产生影响,,我们希望一条SQL语句只在Maste ...
随机推荐
- BZOJ 3223 & 区间翻转
题意: 就是贴个代码,这是我入门题的弱化版..然而一共还是写了40分钟,不专注(一边看比赛一边打)是一个问题,splay每个操作的细节确实有点多(什么时候updata啊..什么时候pushdown啊. ...
- 【BZOJ】2741: 【FOTILE模拟赛】L
题意:给定一个长度为n的序列,m次询问,每次询问一个区间[l, r],求max(Ai xor Ai+1 xor Ai+2 ... xor Aj),其中l<=i<=j<=r.(n< ...
- 期望dp BZOJ3450+BZOJ4318
BZOJ3450 概率期望DP f[i]表示到i的期望得分,g[i]表示到i的期望长度. 分三种情况转移: ① s[i]=‘x’:f[i]=f[i-1],g[i]=0 ② s[i]=‘o’:f[i]= ...
- webdriver中处理alert
1 定义isAlertPresent()供调用: public boolean isAlertPresent() { try { driver.switchTo().alert(); re ...
- 让Xcode的 stack trace信息可读
让Xcode的 stack trace信息可读 昨天在写 iOS 代码的时候,调试的时候模拟器崩溃了.异常停在了如下整个 main 函数的入口处: int main(int argc, char *a ...
- javascript使用两个逻辑非运算符(!!)的原因
javascript使用两个逻辑非运算符(!!)的原因: 在有些代码中可能大家可能会注意到有些地方使用了两个逻辑非运算符,第一感觉就是没有必要,比如操作数是true的话,使用两个逻辑非的返回值还是tr ...
- android-数据存储之手机内部file存储
一.基础概要 1.说明: 1>应用程序运行需要一些较大的数据或者图片可保存在手机内部 2>文件类型:任意 3>路径:/data/data/packageName/files/ 4&g ...
- oracle 学习摘录
(1)oracle插入回车换行符 SQL>insert into A t(t.name) values('aaaaa'||chr(10)||chr(13)||'ccccc'); 已创建 1 行. ...
- 使用文件模拟ASM磁盘
尽管Oracle缺省都是使用裸设备来创建ASM磁盘,但其实Oracle也允许使用普通文件来创建ASM磁盘, 当然这种方法最好只用在测试环境下或者学习环境下,不能用在生产环境下.之所以必须要用裸设备, ...
- 导出excel时,以form方式提交json数据
今天在写项目时写到一个excel的导出,开始想用ajax请求后台后导出,但发现ajax会有返回值,而且ajax无法直接输出文件,而后台的excel导出方法已经封装好,不方便修改. 就改用了提交的方式f ...