私は、本番環境のバックアップから開発データベースを更新するSSISパッケージに取り組んでいます。パッケージは何年も前から存在していますが、開発インスタンスに可用性グループを展開しているため、プライマリレプリカとセカンダリレプリカの両方で機能するようにタスクを変更する必要があります。背景:すべてのインスタンスはSQL Server 2014 SP2です。 1つの運用インスタンス(PD1)、2つの開発インスタンス(DV3とDV7)、および1つのユーティリティインスタンス(DV1)。SSISパッケージがSSISDBに展開され、SQLエージェントジョブが実行されます。 SSISパッケージでは、完全バックアップが取得され、運用環境からネットワーク共有に配置された後、次の一連のタスク(別のSSISパッケージ内)で、プライマリレプリカをホストしているノードを特定する必要があります。私はリストされた手順 here に従ってこの作業を進めていますが、ハードコーディングされている場合はすべて正常に機能します(もちろん、フェイルオーバーが発生した場合は機能しません)。これへのアプローチについて私が考えることができた唯一の方法は、実行時に、どのインスタンスがプライマリであるかを評価してからタスクを続行することです(ちなみに、これらはすべて「SQLタスクの実行」オブジェクトであり、独自の接続定義が必要です)。 )。 ConnectionStringsと変数で式を使用する方法の例をいくつか見ましたが、SQL Serverで以下のクエリから返された値を設定して、正しいインスタンスを返し、パッケージに接続文字列を設定する方法を理解できません。
select cs.replica_server_name
from sys.dm_hadr_availability_replica_states rs
join sys.dm_hadr_availability_replica_cluster_states cs
on rs.replica_id = cs.replica_id
join sys.dm_hadr_name_id_map n
on rs.group_id = n.ag_id
where rs.role = 2
and n.ag_name = 'DVAG001'
理想的には、これらの接続マネージャーが2つあり、1つはプライマリ用、もう1つはセカンダリ用であり、「SQLタスクの実行」オブジェクトで使用できます。その後、すべてが完璧に動作します。これを行う方法は他にもあるかもしれませんが、私はSSISやTSQL以外の開発での経験があまりありません。
更新:上記のプロセスは毎日行われます...そのため、SSISパッケージとSQLエージェントを使用しています。そのため、プロセス全体を自動化し、パッケージ内に必要なすべての値(特にレプリカの状態(プライマリおよびセカンダリ)の決定)を含める必要があるため、手動による介入は必要ありません。
セカンダリレプリカが1つだけの可用性グループがあると仮定します(このサンプルをより多くのレプリカに簡単に拡張できます)。
1。接続
3つの接続が必要になります。
2。変数
データ型がStringの2つの変数を作成する
3。クエリ
SQL実行タスクを使用してクエリ結果セットを変数にマップするには、クエリは1行のみを返す必要があります。各列を必要な変数にマップします。それを知って、私はあなたにクエリを次のように変更しました:
WITH CTE_AGStatus as (
select cs.replica_server_name, rs.role
from sys.dm_hadr_availability_replica_states rs
join sys.dm_hadr_availability_replica_cluster_states cs
on rs.replica_id = cs.replica_id
join sys.dm_hadr_name_id_map n
on rs.group_id = n.ag_id
where n.ag_name = 'DVAG001'
)
select ServernamePrimary = MAX(case when role = 1 then replica_server_name end)
, ServernameSecondary = MAX(case when role = 2 then replica_server_name end)
from CTE_AGStatus
(自由に変更してください。1行だけ返してください)
4。結果セットを変数にマッピングする
SQL実行タスクエディターで、上記のクエリを貼り付け、OLEDB接続「AGリスナー」を設定し、結果セットを「単一行」に変更します
次に、「結果セット」タブに移動して、列を変数にマッピングします
5。接続文字列を変更する
「プライマリ」接続マネージャーをクリックし、「プロパティ」タブに移動して、「式」をクリックし、「サーバー名」プロパティを選択して、式に変数を追加します。
「Secondary」接続マネージャーに対してプロセスを繰り返します
6。プロセスを確認してください
検証するには、他のステップを追加し、ブレークポイントを使用して変数の実行状況を確認できます。次のステップはあなた次第です。これで、AGの各サーバーを指す接続が1つあります。
代替戦略として、T-SQL実行を使用してSSISパラメーターを必要とせずにパラメーターを簡略化することを検討する場合があります(パラメーターは必要ありません)。 SSIS、特にレガシーパッケージは、常にエラーが発生しやすくバグがある可能性があるため、不要な場合は触れたくありません。
[〜#〜] a [〜#〜]まず、「プライマリAGチェック」を、開発サーバーではなく運用サーバー自体で実行することを検討してください。
B。次に、SSISパッケージがまだ存在しない場合は、そこにインポートして、そこで実行します。いずれにせよ、本番プロセスよりも本番環境からのdevリストアを検討するかもしれません。
C。そして最後に、次のコードを使用して、各 "潜在的な"プライマリAGからSSISパッケージの実行(データベースの復元)を呼び出すT-SQLエージェントジョブを実行して、レガシーSSISパッケージをできるだけ変更しないようにします。 -またはそのようなもの-リストAに示すように。
リストA:SQL Serverがプライマリの場合のみ、SQLエージェントジョブを介してSSISパッケージ(データベースの復元)を実行します
--If current server is the primary AG then run the legacy package
if (select a.role_desc FROM sys.dm_hadr_availability_replica_states AS a JOIN sys.availability_replicas AS b ON b.replica_id = a.replica_id WHERE b.replica_server_name like @@Servername) like 'Primary'
begin
Declare @execution_id bigint
EXEC [SSISDB].[catalog].[create_execution] @package_name=N'Package.dtsx', @execution_id=@execution_id OUTPUT, @folder_name=N'AlwaysOn', @project_name=N'MyTestPackage', @use32bitruntime=False, @reference_id=Null
exec ssisdb.catalog.start_execution @execution_id
end
注:
私があなたを正しく理解している場合、開発サーバーには常に同じ名前が付けられます。変更される可能性があるのは、運用サーバーの名前だけです。それを踏まえると、リストAのコード表示を使用すると、少し少ない時間と労力で必要なことを達成できると思います。 SQLバックアップの最後にこの実行を便乗させて、開発環境をより迅速に更新することもできます。