web-dev-qa-db-ja.com

可用性グループのステータスに基づくSSISの条件付き接続

私は、本番環境のバックアップから開発データベースを更新する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エージェントを使用しています。そのため、プロセス全体を自動化し、パッケージ内に必要なすべての値(特にレプリカの状態(プライマリおよびセカンダリ)の決定)を含める必要があるため、手動による介入は必要ありません。

7
SQL_Hacker

セカンダリレプリカが1つだけの可用性グループがあると仮定します(このサンプルをより多くのレプリカに簡単に拡張できます)。

1。接続

3つの接続が必要になります。

  • AGリスナー(どのサーバーがプライマリとセカンダリを保持しているかを返すクエリを実行するため)
  • プライマリ(プライマリサーバーでパラメーター化される)
  • セカンダリ(セカンダリサーバーでパラメーター化される)

2。変数

データ型がStringの2つの変数を作成する

  • サーバー名プライマリ
  • サーバー名セカンダリ

enter image description here

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リスナー」を設定し、結果セットを「単一行」に変更します Execute SQL Task Editor - General tab

次に、「結果セット」タブに移動して、列を変数にマッピングします Result Set map to variable

5。接続文字列を変更する

「プライマリ」接続マネージャーをクリックし、「プロパティ」タブに移動して、「式」をクリックし、「サーバー名」プロパティを選択して、式に変数を追加します。

enter image description here

「Secondary」接続マネージャーに対してプロセスを繰り返します

6。プロセスを確認してください

検証するには、他のステップを追加し、ブレークポイントを使用して変数の実行状況を確認できます。次のステップはあなた次第です。これで、AGの各サーバーを指す接続が1つあります。 enter image description here

8

代替戦略として、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バックアップの最後にこの実行を便乗させて、開発環境をより迅速に更新することもできます。

0
Sting