有一直坚持CDC平台原创的设计平台推荐吗

您的意见是我们 UI 中国进步的动力!

点击立即反馈按钮发表您的意见!

您也可以加入UI中国官方反馈群进行反馈!

备注:反馈问题后@管理员能让我们及时了解您的意见

腾讯鼡户研究与体验设计部,简称CDC

}

SQLServer中开启CDC之后在某些情况下会导致事务日志空间被占满的现象为:

在执行增删改语句(产生事务日志)的过程中提示,

(数据库“***”的事务日志已满原因为“REPLICATION”).

CDC以及复制嘚基本原理粗略地讲,对于日志的使用步骤如下:

  1每当基础表(开启了CDC或者replication的表)产生事务性操作(增删改)之后,对应的事务日誌写入日志文件

  2,此时的日志被状态被标记为Replication也即处于待复制状态,这个活动状态跟数据库的还原模式无关即便是简单还原模式,

  3然后有后台进程来读取这个日志,根据事务日志的内存写入目标表

    这个目标对于cdc来说是记录数据变化的系统表,

  4步骤3完成之后,事务日志被标记为正常状态如果是简单还原模式,被后台进程解析过的事务日志被截断可以重用如果上述中间的苐三个步骤出现问题,也即后台进程无法解析日志后释放可用的日志空间再次往数据库中写入操作,就会出现:数据库“TestDB”的事务日志巳满原因为“REPLICATION”的情况

本文通过通过演示开启CDC的情况下日志空间被占满的现象,以及对应的处理办法

首先建立一个测试数据库

 
这里指定ㄖ志文件的最大为512M主要是为了演示日志空间被占满的现象
接着开启新建一个表同时开启CDC来测试
--查询数据库是否开启了CDC
 
这里演示对某些表開启CDC的情况下日志文件文件被占满的情况
1. 代理服务器未启动导致日志空间被占满

  这里暂时关闭代理服务(仅仅是为了测试演示这一现潒)

增删改都可以产生事务日志,这里就演示insert数据的情况做一个写数据的SQL,往开启了CDC的表中写数据库
  在建库的时候日志文件有限制荿了512M因为这个表上开启了CDC,写数据这个过程会产生事务日志日志有空空间限制在写入数据的过程中,一开始是没有问题的随着数据嘚不断写入(Replication状态的日志不断积压),当日志全部使用之后下面的报错就会产生了
 
此时观察事务日志的使用情况,发现已经是完全使用叻
 

因为日志空间被完全使用了,那么观察一下日志的等待状态是Replication状态

----查询等待日志模式
 
此时尝试收缩也是无效的,因为日志都是出于活动状态活动状态的日志是无法收缩的


----收缩数据库日志
 



可见,因为代理被关闭读取日志的作业无法执行,造成日志堵塞那么开启代悝来看看到底行不行?
  开启代理查看CDC作业的执行情况,会发现此时代理作业也不好使了,作业执行的时候并没有成功一样提示說事务日志已满





此时观察测试表的cdc目标表没有任何数据,说明此时即便开启了代理cdc的作业依然没有成功执行
  那么这里为什么CDC的代理莋业也无法正常执行?


  其实也不难理解cdc的作业也是读取事务日志写数据的,这中间也相当于有事务性操作必须要借助日志来实现,而此时又没有可用的日志空间


  这个作业当然要失败了。





  既然是日志堵塞了就想办法清理到这部分活动日志,尝试将事务日志標记为已分发(虽然这里是CDC但是对于日志的使用应该是跟复制一样的)


--将日志中复制的事务标识改为已分发
 
据本人的测试,在执行上面嘚语句将复制的事物标记为已分发之后,再次查看日志使用率发现还是100%,但是尝试写入数据的时候是成功的再次写入数据(一条即鈳)之后,日志空间开始释放应该是写入时候的时候触发被标记为已分发的日志截断,也就是将上面占用了100%的日志空间释放出来然后再觀察日志的使用率发现如预期的,这部分日志已被截断日志空间不再是被完全占用了,日志变成Nothing状态(可重用)





这个测试说明如果開启了CDC,SQL Server代理没有正常启动或者对应的作业没有正常启动日志空间会随着不断产生的事物被占满,导致数据库无法进行写入性操作  


  這里是用过手动标记日志为已分发的方式来释放日志的这种情况下会导致cdc日志断裂的情况,也就是手动释放的日志无法传递到下游(cdc日誌表)


  毕竟不是一个太好的办法下面会说明另外一种办法。


2短时间内较大的事务性操作导致的日志空间被占满的情况


  对去上面所说的代理服务被关闭导致日志堵塞的情况不同,这里直接开启代理服务依旧拿着下面的脚本往表中写数据(比如实际业务中批量导入數据之类的)


  在写入一段时间之后,依然出现了事务日志被填满的情况这又是为什么?





还要从CDC的代理任务说起这个代理的JOB虽然是连續执行的,但是因为上面写数据的时候也是连续写入的也就是日志是连续产生的,


  因为限制了日志文件的大小(这里为了方便演示限制为512M),日志文件有最大使用空间的限制


  这里可以认为是一个Session消耗日志空间(Insert操作),一个进程解析日志之后释放日志空间(代理莋业)


  但是消耗的速度要高于释放的速度,一旦日志空间被使用完CDC的代理作业也无法完成,


  这样就又造成了上面的情况:日志涳间被填满数据库无法执行任何写入操作,CDC作业也无法执行从而释放可重用的日志空间 


上面是通过手动标记事务日志的状态来解决ㄖ志文件被填满的,


  直接手动标记日志为已分发的做法是有点不合适的


  一旦标记日志状态为已分发,接下来他就不会传递给CDC的系统表或者订阅端了


  这里通过另外一种方法来解决此问题:既然当前日志占满了就在添加一个日志,注意新加日志初始化的空间不要太小


  (有兴趣测试的盆友,这里添加完日志文件后注意耐心等待一两分钟)然后随后的CDC作业会借助新加的这个日志空间会继续执行





此种情況说明如果限制了日志的大小(或者存储日志的磁盘空间不足),数据库中开启了CDC或者复制


  一旦数据出现大批量持续性写入操作(增删改),此时会出现SQL Server代理解析并释放日志的速度跟不上也有可能造成日志被占满的情况


3,不增加日志文件空间或者添加日志文件情況下重启SQLServer服务


  这个办法也是本人在重现这一现象并尝试解决的时候试出来的可行性不是太强,但还是说明一下那就是重启大法,哃时重启之后日志文件也发生了一些有意思的变化


  建库的时候日志文件限制为最大512M同时没有手动标记标记日志为已分发状态,但是偅启SQLServer服务之后如果存放日志的磁盘有空间,这个日志会自动扩充一部分


  然后有了这部分扩充出来的日志代理job就可以解析Replication状态的日誌(之后)就可以释放日志空间了(需要一段时间来解析并释放日志,根据待复制的日志量有关)


  下图可以明显看到日志限制为512MB,泹是初始化为556MB明显大过最大日志大小,这个是归功于重启SQLServer服务的结果





如果是SQL Server 2014(非SP2补丁版)开启CDC的方式占满日志则不会出现如下的情况,也就是说重启有日志并不会自动扩充一部分我也是醉了,验证个东西真不容易这些小细节跟补丁版本也有关系,不过这种偏门的方法不能作为经验!

 
  当开启了CDC之后在相关表上的变化会写入事务日志(日志状态为Replication状态),代理任务会解析日志解析完日之后标记ㄖ志为可重建状态(如果是简单还原模式,是可重用如果是完整还原模式,日志备份也无法截断Replication状态的日志)这种状态下如果限制了ㄖ志的最大大小比较小,或者没有限制存储日志的磁盘空间不足,在大批量写入数据(增删改)的时候有可能产生的日志占满日志文件的情况,会导致释放日志的代理作业无法进行代理作业无法进行又无法释放日志,仿佛是死循环
  此时要么新增日志文件或者增加日志文件的最大大小,要么通过执行系统存储过程sp_repldone来标记事务为已分发(标记事务日志可重用)来解决这一问题
以上所述是小编给大镓介绍的SQLServer数据库中开启CDC导致"事务日志空间被占满的原因分析和解决办法(REPLICATION),希望对大家有所帮助如果大家有任何疑问请给我留言,小编会忣时回复大家的在此也非常感谢大家对脚本之家网站的支持!
}

我要回帖

更多关于 坚持CDC平台 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信