CDC作业历史记录无法删除问题
背景
数据库开启CDC功能后,每天会生成大量的历史记录,即使达到参数“每个作业的最大历史记录“的阈值后也不会被删除,导致其它作业的历史记录被删除,无法查看以前的执行情况,非常不方便。
现象
数据库开启CDC后会创建“capture”和“cleanup”两个作业,capture作业会生成大量的历史记录,而且参数“每个作业的最大历史记录”不起作用,一直不删除。


分析
首先通过跟踪定位到SQL Agent服务在执行作业时调用存储过程msdb.dbo. sp_sqlagent_log_jobhistory处理作业历史记录。查看该存储过程的定义,首先把当前运行数据插入到历史记录表中。

然后通过@step_id判断是整个作业完成的记录还是执行过程中步骤的记录,如果是作业已经完成的记录,执行存储过程msdb.dbo.sp_jobhistory_row_limiter对历史记录进行清理。

查看存储过程msdb.dbo.sp_jobhistory_row_limiter的定义,首先从注册表中获取参数“所有作业最大行数”和“每个作业最大行数”的值。


先根据参数“每个作业最大行数”判断当前作业是否超过限制,并删除旧的记录。

然后根据参数“所有作业最大行数”判断所有作业历史记录是否超过限制,并删除旧的记录。

接下来分析为什么CDC的历史记录无法删除,通过跟踪定位到捕获作业调用存储过程[sys].[sp_cdc_scan]在一个没有退出方式的循环中扫描事务日志,并调用存储过程msdb.dbo. sp_sqlagent_log_jobhistory 记录历史记录,因为传递的@step_id的值代表这是执行步骤的记录,不是作业完成的记录,因此不会触发清理日志的存储过程,导致历史记录越积累越多。

总结:
capture作业一直是运行的,所以记录的都是作业步骤的日志,不会执行到清理历史记录的步骤,导致历史记录越积累越多;
其它作业执行完成清理历史记录时,因为capture作业的历史记录越积累越多,达到“所有作业最大行数”的阈值,删除所有作业旧的历史记录。capture作业运行频繁,所以保留的大都是capture作业的历史记录,其它运行不频繁的作业的历史记录被删除。
解决
方法一:创建一个新的作业,定期删除CDC的作业历史记录。
1 CREATE PROC [dbo].[usp_gt_delete_cdc_job_history]
2 AS
3 BEGIN
4 DECLARE @job_id UNIQUEIDENTIFIER;
5
6 DECLARE cdc_job_cursor CURSOR FOR SELECT
7 job_id
8 FROM
9 msdb.dbo.cdc_jobs
10 WHERE
11 job_type = 'capture';
12
13 OPEN cdc_job_cursor;
14 FETCH NEXT FROM cdc_job_cursor INTO @job_id;
15 WHILE @@FETCH_STATUS = 0
16 BEGIN
17 EXECUTE msdb.dbo.sp_jobhistory_row_limiter @job_id;
18
19 FETCH NEXT FROM cdc_job_cursor INTO @job_id;
20 END
21
22 CLOSE cdc_job_cursor;
23 DEALLOCATE cdc_job_cursor;
24 END
方法二:到msdb中修改存储过程的定义,增加对CDC作业处理的逻辑。该方式已经反馈给微软,在SQL Server下一个版本会采用,也算对SQL Server做一点小贡献。


以下是具体的代码。
1 ELSE
2 BEGIN
3 IF EXISTS(SELECT 1 FROM msdb.sys.tables WHERE schema_id = SCHEMA_ID('dbo') AND name = 'cdc_jobs')
4 BEGIN
5 IF EXISTS(SELECT 1 FROM msdb.dbo.cdc_jobs WHERE job_id = @job_id AND job_type = 'capture')
6 BEGIN
7 EXECUTE msdb.dbo.sp_jobhistory_row_limiter @job_id
8 END
9 END
10 END
产品&服务
SQL专家云数据库智能运维平台
Moebius数据库多活集群
北京格瑞趋势科技有限公司是聚焦于数据服务的高新技术企业,成立于2008年,创始团队及核心技术人员来自微软和雅虎。微软数据平台金牌合作伙伴。通过产品+服务双轮驱动的业务模式,15年间累计服务4000+客户,覆盖互联网、市政、交通、电信、医疗、教育、电力、制造业等各个领域。
CDC作业历史记录无法删除问题的更多相关文章
- kettle删除资源库中的转换或者作业
在资源库中新建转换,作业都很简单,那么加入现在不需要其中某个转换或者作业该怎么办呢? 下图是已经存在的转换跟作业 现在需要删除aa这个转换 操作步骤如下: 1.工具----资源库----探索资源库 出 ...
- linux删除或隐藏命令历史记录history
1.环境变量添加HISTCONTROL = ignorespace 在命令前面插入空格,这条命令会被 shell 忽略,也就意味着它不会出现在历史记录中.但是这种方法有个前提,只有在你的环境变量 HI ...
- Git永久删除文件和历史记录
目录 Git永久删除文件和历史记录 使用filter-branch 添加到.gitignore文件里并push修改后的repo 清理和回收空间 Git永久删除文件和历史记录 造成你想从git存储库中永 ...
- 如何批量删除QQ浏览器指定历史记录和导出指定的历史记录
QQ浏览器的历史记录只有清空历史记录和删除选中项两个功能.有时我不想删除所有的历史记录,只是想删除指定的历史记录保留对自己有用的历史记录,方便自己以后查找.但是删除选中项功能只能一项一项的选择,才能批 ...
- at, batch, atq, atrm - 排队、检查或删除以后要执行的作业
总览 at [-V] [-q 队列] [-f 文件] [-mldbv] 时间 at -c 作业 [作业...] atq [-V] [-q 队列] [-v] atrm [-V] 作业 [作业...] b ...
- 每天一个linux命令(49):at命令 atrm删除作业,由作业号标识。
atq命令 例如:从现在起三天后的下午四点运行作业at 4pm + 3 days:在July 31上午十点运行作业at 10am July 31:明天上午一点运行作业at 1am tomorrow. ...
- Replication--复制与CDC和镜像
复制和CDC 都是使用logreader来从日志中读取数据的变更,然后写入到分发库(复制)或变更表中. 1> 单独创建复制发布 在该情况下,会在分发服务器上创建日志读取代理作业(ServerNa ...
- SQL SERVER 作业浅析
作业介绍 SQL SERVER的作业是一系列由SQL SERVER代理按顺序执行的指定操作.作业可以执行一系列活动,包括运行Transact-SQL脚本.命令行应用程序.Microsoft Activ ...
- SQL Server是如何让定时作业
如果在SQL Server 里需要定时或者每隔一段时间执行某个存储过程或3200字符以内的SQL语句时,可以用管理->SQL Server代理->作业来实现. 1.管理->SQL S ...
- SQL SERVER 作业(或叫执行计划)
如果在SQL Server 里需要定时或者每隔一段时间执行某个存储过程或3200字符以内的SQL语句时,可以用管理->SQL Server代理->作业来实现. 1.管理->SQL S ...
随机推荐
- Ant Design Vue 单文件上传Upload
单文件上传 <a-upload name="file" :beforeUpload="beforeUpload" :multiple="fals ...
- vue在render函数中如何实现v-model和事件绑定(4)
1.h函数的三个参数 第一个参数是必须的. 类型:{String | Object | Function} 一个 HTML 标签名.一个组件.一个异步组件.或一个函数式组件. 是要渲染的html标签. ...
- 【0基础学爬虫】爬虫基础之HTTP协议的基本原理介绍
大数据时代,各行各业对数据采集的需求日益增多,网络爬虫的运用也更为广泛,越来越多的人开始学习网络爬虫这项技术,K哥爬虫此前已经推出不少爬虫进阶.逆向相关文章,为实现从易到难全方位覆盖,特设[0基础学爬 ...
- React中引入外部js文件
假设需要引入本地的一个jquery库: <script src="http://127.0.0.1:8080/plugins/jquery.min.js" type=&quo ...
- iOS转场之present与dismiss的使用
present的使用方式 present只能是A present B , B present C , C present D这样的链式弹出. 不能A present B , A present C , ...
- 一篇学会软硬链接|快捷方式|操作系统|centos7
前言 那么这里博主先安利一些干货满满的专栏了! 首先是博主的高质量博客的汇总,这个专栏里面的博客,都是博主最最用心写的一部分,干货满满,希望对大家有帮助. 高质量博客汇总https://blog.cs ...
- RocketMQ—RocketMQ发送同步、异步、单向、延迟、批量、顺序、批量消息、带标签消息
RocketMQ-RocketMQ发送同步.异步.单向.延迟.批量.顺序.批量消息.带标签消息 发送同步消息 生产者发送消息,mq进行确认,然后返回给生产者状态.这就是同步消息. 前文demo程序就是 ...
- 【译】介绍 MSTest Runner – CLI、Visual Studio 等
原文 | Amaury Levé, Marco Rossignoli, Jakub Jareš 翻译 | 郑子铭 我们很高兴推出 MSTest runner,这是一个用于 MSTest 测试的新型轻量 ...
- 《ASP.ENT Core 与 RESTful API 开发实战》-- (第5章)-- 读书笔记(中)
第 5 章 使用 Entity Framework Core 5.3 重构仓储类 创建一个通用仓储接口 namespace Library.API.Services { public interfac ...
- Swoole从入门到入土(27)——协程[协程容器]
这一章开始,我们要开始全方位讨论Swoole为我们提供的协程机制.在swoole中所有的协程必须在协程容器里面创建(Swoole\Coroutine\Scheduler),Swoole 程序启动的时候 ...