SQL Serverでサブスクリプションを非アクティブとしてマークしないようにする方法はありますか?
接続に問題があり、サブスクリプションを毎回再初期化する必要がない場合は、散発的に発生します。
サブスクリプションが期限切れとしてマークされていることは話していません...非アクティブと同じように。
保持は0(無限)に設定されています。 15GBデータベースをWAN経由でサブスクライバーに再初期化する必要があるよりも、大きなディストリビューションデータベースが必要です。とにかく、ここでの本当の問題は、彼らが数時間以内に、あるいは時には数日以内に非アクティブとしてマークされていることです...それは散発的なようです。 SQLの知恵で、SQLを非アクティブとマークするように決定した理由を伝える方法はありますか?
はい、t-SQLとsqlエージェントジョブを使用してプログラムで実行できます。
基本的に、distribution..MSSubscriptionsをクエリし、ステータス列の値が0(非アクティブ)であることを確認する必要があります。
サブスクリプションのステータス:0 =非アクティブ。 1 =購読済み。 2 =アクティブ
以下のT-SQLが役立ちます:
-- Author: Kin Shah
-- Date: 4-1-2013
-- For dba.stackexchange.com
-- Good to find out
-- publisher_id
-- publisher_db
-- publication_id
-- subscriber_id
-- subscriber_db
select * From distribution..MSsubscriptions
--- based on the above values, run below statement
--- this can be run using SQLAgent job
if exists (select 1 from distribution..MSsubscriptions where status = 0)
begin
UPDATE distribution..MSsubscriptions
SET STATUS = 2
WHERE publisher_id = '--publisher_id -- will be integer --'
AND publisher_db = '--publisher db name ---'
AND publication_id = '--publication_id -- will be integer --'
AND subscriber_id = '--subscriber_id -- will be integer ---'
AND subscriber_db = '-- subscriber_db ---'
end
else
begin
print 'The subscription is not INACTIVE ... you are good for now .... !!'
end
によると、設定が「無期限」に設定されているにもかかわらず、サブスクリプションはパブリッシャーとの同期に失敗し、非アクティブとしてマークされます :
非アクティブ化の原因を見つけるには、Distributionプロパティでトランザクション保持期間を確認する必要があります。これが3時間などの低い数値に設定されている場合、これは、サブスクライバーが3時間同期しない場合、ディストリビューションクリーンアップエージェントがディストリビューション内のコマンドテーブルを切り捨てるため、サブスクライバーが非アクティブとしてマークされることを示します。
コマンドはディストリビューターから削除されるため、サブスクライバーを再初期化する以外に方法はありません。
また、ディストリビューターが同期できない原因を見つけるために、ディストリビューションデータベースの以下の表でディストリビューションの履歴を確認できます。
msdistribution_agents
msdistribution_history
また、製品ドキュメントの Subscription Expiration and Deactivation から:
サブスクリプションが期限切れにならないように指定することもできます(@retentionの値は0)。ただし、メタデータをクリーンアップできないため、この値を使用しないことを強くお勧めします。
可能な解決策については、このMSDNフォーラムスレッドもお読みください: 再アクティブ化のために非アクティブなサブスクリプションを自動的にマークする
これが Kin's answer のスクリプトのバージョンです。誰かが役立つと思った場合に備えて、インタラクティブに実行するように変更しました。
--===================================
-- please note that this should NOT be done in production
--
-- there is likely to be data loss, as we know we lost track of some rows in distribution.
--===================================
-- run on replication source having issue
select *
from distribution..MSsubscriptions sub
WHERE publisher_id = sub.publisher_id
AND publisher_db = sub.publisher_db
AND publication_id = sub.publication_id
AND subscriber_id = sub.subscriber_id
AND subscriber_db = sub.subscriber_db
and status = 0
if exists (select 1 from distribution..MSsubscriptions where status = 0)
begin
begin tran
UPDATE distribution..MSsubscriptions
SET STATUS = 2
from distribution..MSsubscriptions sub
WHERE publisher_id = sub.publisher_id
AND publisher_db = sub.publisher_db
AND publication_id = sub.publication_id
AND subscriber_id = sub.subscriber_id
AND subscriber_db = sub.subscriber_db
and status = 0
-- if you do not believe in paranoia checks, then comment out the following roll back
rollback -- the default is set to 'roll back' to force DBA to manual run lines in this script
commit
end
else
begin
print 'No subscriptions are INACTIVE ... you are good for now .... !!'
end