简体   繁体   English

SQL Server事务复制筛选器

[英]SQL Server transactional replication filter

I have a very large table from which I need to extract a subset of records, the last 30 days records, and to replicate this 30 days records to a second database, for reporting purposes. 我有一个很大的表,我需要从中提取记录的子集(最近30天的记录),并将这30天的记录复制到另一个数据库中,以进行报告。 Now I am using transactional replication where I added a filter in the published articles to isolate the 30 days records, to get a near real time replication envirnment. 现在,我使用事务复制,在发布的文章中添加了一个过滤器,以隔离30天的记录,从而获得近乎实时的复制环境。

The issue I have is that : the replication seems to be incremental, meaning that the most recent records are added to the replica, but the older records are not removed so it keeps getting large. 我的问题是:复制似乎是增量的,这意味着将最新记录添加到副本中,但是不会删除较旧的记录,因此它会变得越来越大。

When a record that is out of filtering criteria is updated and enters again under the filtering criteria the replication crashes with an "duplicate primary key error". 当超出过滤条件的记录被更新并根据过滤条件再次输入时,复制将因“重复的主键错误”而崩溃。

How to make it work so that the replica to contain only the last 30 days of data ? 如何使其工作,以使副本仅包含最近30天的数据? Is the above described behaviour something that I shall expect to see ? 上述行为是我期望看到的吗?

Many thanks, 非常感谢,

Well the simplest way, is not to use mssql's filter. 最简单的方法就是不使用mssql的筛选器。 The simplest way is to change the SPS used for update and delete with custom sps so that you will not get errors on deleting (absent rows) and updating (absent rows). 最简单的方法是使用自定义sps更改用于更新和删除的SPS,这样您在删除(缺少行)和更新(缺少行)时不会出错。 This is done from the article's advanced properties. 这是通过文章的高级属性完成的。 In case of a delete you should just use a merge and filter there your criteria. 如果是删除,您应该只使用合并并在那里过滤您的条件。

Also have a job that deletes from the tables what you need to have deleted. 也有一项工作将从表中删除您需要删除的内容。 Of course you will need to be very careful when doing structure updates, but it is doable. 当然,进行结构更新时需要非常小心,但这是可行的。

Another more ugly way is to keep sql's stored procedures and just ignore the errors (through the distribution agent .. -SkipErrors 2601:2627:20598). 另一种更丑陋的方法是保留sql的存储过程,而忽略错误(通过分发代理.. -SkipErrors 2601:2627:20598)。 This will require again a job to delete old rows and it will not bring you back into your scope the old rows that are just updated. 这将再次需要删除旧行的工作,并且不会将刚刚更新的旧行带回您的范围。 All in all the first solution should be the best one. 总而言之,第一个解决方案应该是最好的解决方案。

Hope it helps. 希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM