解决大量更新引起同步链延时问题

原文:解决大量更新引起同步链延时问题

 前言:

在SQLServer数据库中,当我们对一个位于同步链上的表进行更新时,如果更新的记录数也非常多,几百或是几千万,那么批量更新该表会造成同步链的大量延时(甚至有可能崩溃掉,即使同步链不崩溃,等的人也要崩溃了)。

 原因:

一般情况下,Replication是根据我们更改的数据一条条更改记录的,也就是说我们在发布端下达如下的语句:

update TestTb set TT=‘xxxx‘ where ustate=0

如果这条更新语句,修改的数据量是一千万条的话,那Replication同步链需要传递一千万条如下的语句到订阅端去执行:

exec [dbo].[sp_MSupd_dboTestTb] default,‘xxxx‘,default,2,0x02

如果我们有8台订阅端,而我们更新的数据也不是这么简单的数据的话(如更新一些nvarchar(1000)之类的),这个数据流量是非常恐怖的。

解决办法:

基于以上原因,我们在对同步链上的表进行大规模更新操作时,必须要非常小心,避免数据的大量更新;但是如果业务有此要求,必须要在同步的表上更新这么多数据量,如何办呢?

1.  如果你已经在发布端直接运行了类似上面的语句,那就只有一个字:“等”(当然也可以将表从同步链中去掉);

2.  我们可以采用分批处理的方式来更新同步链,一批次处理几百或者一千条数据,处理完一批后,等待10s钟,再运行下一批,类似语句如下(常用):

DECLARE @count int

,@sumcount int

,@subcount int

SET @sumcount=0

set @subcount=0

SELECT

@count=COUNT(0)

FROM TestTb where ustate=0

WHERE ustate=0

WHILE(@sumcount<@count and @subcount >= 1000)

begin

UPDATE TOP (1000) TestTb

SET TT=‘XXXX‘ where ustate=0

set @subcount=@@ROWCOUNT

set @sumcount=@sumcount+1000

waitfor delay ‘00:00:10‘

end

3.  如果更新的数据很大,用第二种方法将会消耗很长的时间,等不起呀;有没有更好的方法呢?我们可以通过使用临时存储过程来更新数据,下面我们通过一个实例来看看如何操作:

--新建一个测试表

CREATE TABLE TestTb

(

id int identity(1,1) primary key ,

,name varchar(20)

,ustate smallint

)

--插入测试数据

insert into TestTb(name,ustate)

values(‘AAAAA‘,0),

(‘BBBBB‘,1),

(‘CCCCC‘,0),

(‘DDDDD‘,1),

(‘EEEEE‘,0),

(‘FFFFF‘,1)

--新建一个存储过程

create proc usp_updateTestTb

as

begin

update TestTb set name=‘KKKKKK‘ where ustate=1

end

我们把表TestTb 和 usp_updateTestTb 都建到同步链上,需要注意的是,TestTb表结构在订阅端需要将Identity 属性去掉;usp_updateTestTb需要选择同步更改和运行,即将同步的Replicate属性 选为“Execution of the stored procedure”,这样在发布端执行存储过程时,订阅端也会执行相应的存储过程,而不是分条执行存储过程中影响的每一条语句;

同步建好后,我们在订阅端打开Profile,选择我们要跟踪的库,然后在订阅端做以下测试:

--先查下满足记录的条数

select * from TestTb where ustate=1

--直接运行更改语句

update TestTb set name=‘PPPPPP‘ where ustate=1

(3 row(s) affected)

--更改后订阅端的数据

select * from TestTb

我们到订阅端的Profile中去看看传递过来的语句情况:

s

可以看到有三条语句传过来了;

接下来我们运行存储过程usp_updateTestTb,这个SP也是更新TestTb中三条数据,我们看看Profile中又有什么信息

--发布端运行usp_updateTestTb

exec usp_updateTestTb

(3 row(s) affected)

--订阅段数据

select * from TestTb

订阅端Profile的数据:

图中我们可以看到,订阅端也只是运行了usp_updateTestTb这个存储过程,并不会传递三条修改的记录过来,如果这个sp更新的数据很大,这样将大大减少同步链传递的数据量(如果我们更改的记录是一千万,传递的也就一条命令),数据的更新只相当于本地库的更新,对同步链没有影响;同时,基于对系统影响的考虑,我们把方法二和方法三两中方法结合起来运用,能收到很不错的效果。

原文地址:https://www.cnblogs.com/lonelyxmas/p/8360680.html

时间: 2024-08-02 07:43:47

解决大量更新引起同步链延时问题的相关文章

解决cocoaPods更新缓慢

1 pod install --verbose --no-repo-update 2 pod update --verbose --no-repo-update 解决cocoaPods更新缓慢,码迷,mamicode.com

解决MySQL主从不同步问题

解决mysql主从不同步 今天发现Mysql的主从数据库没有同步 先上Master库: mysql>show processlist;   查看下进程是否Sleep太多.发现很正常. show master status; 也正常. mysql> show master status; +-------------------+----------+--------------+-------------------------------+ | File              | Pos

myeclipse 中 svn 更新 提交 同步资源库 详细解释下他们的功能

原理是这样的 svn服务器一般放在公共的服务器上,大家连这个服务器,在MyEclipse上使用svn控件 可以下载svn上的项目至本地,所以很多公司将开发要用到的软件都放在svn上,有同事来只要连上svn 就可以把需要的东西下下来了 1.update更新更新,是指 服务器上变动了的 而你本地没有变动,需要你更新, 2.commit提交提交,是指服务器上没有的,也就是你改过的东西,你需要将代码提交,其他同事更新你的代码 3.synchronize同步同步,是在更新提交之前做的工作,更新提交前先同步

Android: 解决SVN更新项目后报错

解决SVN更新项目后报错 解决方法: 1.查看AndroidManifest.xml 和   project.properties文件是否配置正确,不正确 就修改适合当前开发环境的配置: 2.选择ADT的菜单项Project------------->clean  清理项目: 3.还不行的话,最后就重新打开ADT,基本上就解决了,再报错的话,那就是代码问题了,代码错误. PS: 项目不能生成R.java文件,Clean也不行的话,一定要看控制台输出的错误信息,根据错误信息去更改代码或文件,例如r

J2EE编程心得-使用Hibernate出现的错误及解决方法 更新中...

1.  使用Hibernate时出现Session was already closed异常 出现此异常的原因是Session已经被关闭 如果不是使用的SessionFactory.getSession()来获得Session. 而是使用SessionFactory.getCurrentSession()方法来获得Session时,当事务结束的时候,不管是提交还是回滚事务,hibernate会自动关闭Session的, 所以不需要手动关闭. public boolean insert(LiftI

解决kali更新出现文件尺寸不符问题

解决kali更新出现文件尺寸不符 更新kali时出现如下图错误: 终端进入更新源文件:vim  /etc/apt/sources.list,中把http改成https就解决了 原文地址:https://www.cnblogs.com/liang-chen/p/11733875.html

如何实现 MySQL 的读写分离?MySQL 主从复制原理的是啥?如何解决 MySQL 主从同步的延时问题?

高并发这个阶段,肯定是需要做读写分离的,啥意思?因为实际上大部分的互联网公司,一些网站,或者是 app,其实都是读多写少.所以针对这个情况,就是写一个主库,但是主库挂多个从库,然后从多个从库来读,那不就可以支撑更高的读并发压力了吗? 如何实现 MySQL 的读写分离? 其实很简单,就是基于主从复制架构,简单来说,就搞一个主库,挂多个从库,然后我们就单单只是写主库,然后主库会自动把数据给同步到从库上去. MySQL 主从复制原理的是啥? 主库将变更写入 binlog 日志,然后从库连接到主库之后,

今天解决了价位没有同步更新的问题

我在save方法里的array里放了两个参数,希望一次保存两个字段. save(array('rank_price'=>$price)); 结果报错: syntax error, unexpected T_DOUBLE_ARROW 最后拆分成两次保存,就OK了. 应该可以通过事先把要保存的所有字段赋值给一个变量,实现一次性save. 暂时先不优化,解决问题就好啦.

SCCM2012软件更新点同步失败问题(0x80131505,WSUS服务未启动)

今天测试升级win7专业版到Win10,浏览微软官网发现免费升级一直未推送.查看官方说明要求操作系统SP1.IE升级到11.安装KB2952664补丁.发现这台PC没有打上KB2952664的补丁,怀疑WSUS补丁更新有问题,检查SCCM发现以下错误: 同步状态:失败,上一个同步错误代码:0x80131505 检查Windows日志,提示WSUS服务未启动,不是有效的Win32应用程序. 手动启动WSUS服务,提示错误193:0xc1 重启系统,在登录时有以下错误信息,C盘多了一个program