AWS から Google Cloud への Microsoft SQL Server の移行

Last reviewed 2023-05-05 UTC

このドキュメントでは、Amazon Elastic Compute Cloud(Amazon EC2)にインストールされている Microsoft SQL Server インスタンスを Google Cloud の Compute Engine 上の Microsoft SQL Server インスタンスに移行する方法について説明します。この移行は、Microsoft SQL Server が提供する組み込みのデータベース テクノロジーのみに基づいて行われます。この方法は実質的に、Always On 可用性グループを使用するゼロ ダウンタイムの方法です。Always On 可用性グループは、VPN を介して AWS と Google Cloud にまたがっており、Microsoft SQL Server データベースのレプリケーションを可能にします。このドキュメントは、ネットワークの設定、Google Cloud、Compute Engine、AWS、Microsoft SQL Server に精通していることを前提としています。

レプリケーションのみを実行する場合も、このチュートリアルの手順を行うことができますが、テストデータを追加した後で停止し、カットオーバー手順を省略します。

目標

  • Microsoft EC2 の Microsoft SQL Server と Compute Engine の Google Cloud 上の Microsoft SQL Server にまたがる、マルチクラウド Microsoft SQL Server Always On 可用性グループをデプロイします。
  • Amazon EC2 でプライマリ Microsoft SQL インスタンスを設定します。
  • AWS のプライマリ Microsoft SQL Server のセカンダリ(データ レプリケーションのターゲット)として、Google Cloud で Microsoft SQL Server インスタンスを設定します。
  • Google Cloud のセカンダリ Microsoft SQL Server を Google Cloud のプライマリ Microsoft SQL Server にすることで、データの移行を完了します。

費用

このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。 新しい Google Cloud ユーザーは無料トライアルをご利用いただける場合があります。

このチュートリアルでは、費用が発生する可能性がある AWS のリソースも必要になります。

始める前に

  1. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

    プロジェクト セレクタに移動

  2. Google Cloud プロジェクトで課金が有効になっていることを確認します

  3. Google Cloud コンソールで、「Cloud Shell をアクティブにする」をクリックします。

    Cloud Shell をアクティブにする

データベース移行について

データベースを移行すると、ソース データベースからターゲット データベースにデータが移動します。通常、データのサブセットを移行することも、ソース データベースとターゲット データベースで別のスキーマを設定することもできます。ただし、このチュートリアルでは、変更を加えずに完全なデータベースを移行する必要がある同機種のデータベース移行について説明します(ターゲット データベースは、ソース データベースのコピーになります)。

ダウンタイムが発生しないデータベース移行

「ダウンタイムなし」とは、移行中、ソース データベースにアクセスするクライアントが引き続き稼働し、中断されないことを意味します。移行の完了後にクライアントがターゲット データベースに再接続する必要がある場合にのみ、ダウンタイムが発生します。この方法は完全なゼロ ダウンタイムではありませんが、この用語は、ダウンタイムが最小限になるシナリオでも使用されます。

データベース移行に関する全般的な説明については、データベースの移行: コンセプトと原則(パート 1)およびデータベースの移行: コンセプトと原則(パート 2)をご覧ください。これらの記事では、さまざまなシナリオで発生しうるデータベース移行の複雑性について概説しています。

Microsoft SQL Server テクノロジーを使用したデータベースの移行

一部のデータベース移行テクノロジーでは、個別のコンポーネントとサービスが用意されています。データベースの移行でソース データベースのコピーが必要な場合は、組み込みの Microsoft SQL Server テクノロジーを使用できます。

このチュートリアルでは、Microsoft SQL Server Always On 可用性グループ テクノロジーを使用して、ソース データベース(プライマリ)をターゲット データベース(セカンダリ)に接続します。このテクノロジーは、プライマリ データベースからセカンダリ データベースへの非同期レプリケーションを可能にするものです。プライマリ データベースは Amazon EC2 にあり、セカンダリ データベースは Compute Engine 上の Google Cloud にあるため、データベースの移行はレプリケーションにより行われます。すべてのデータが非同期レプリケーションによって移行されると、セカンダリがプライマリに昇格され、クライアントは新しいプライマリに再接続して処理を継続できます。

このアプローチは、テスト ターゲット データベースに対するトライアルのレプリケーションによる明示的なテストをサポートします(レプリケーションを開始し、しばらく実行した後、レプリケーションを停止します)。テスト ターゲット データベースは一貫した状態であり、このデータベースを使用して、アプリケーションをテストできます。テストが完了したら、テスト ターゲット データベースを削除し、ライブ データベースのレプリケーションを開始できます。

マルチクラウド データベース移行アーキテクチャ

次の図は、マルチクラウド データベース移行の全体としてのデプロイ アーキテクチャを示しています。

Always On 可用性グループは、AWS データベースを Google Cloud データベースに接続します。

上の図は、Amazon EC2 インスタンスとしての AWS のソース(プライマリ)SQL Server データベースを示しています。この図には、Google Cloud のターゲット データベース(セカンダリ)も示されています。データベースは、Always On 可用性グループによって接続されています。AWS と Google Cloud の間のネットワーク接続は、安全な HA VPN 接続であると想定されます。

マルチクラウド Microsoft SQL Server 可用性グループの設定

次のセクションでは、プライマリ ノードが AWS に、セカンダリ ノードが Google Cloud に存在する 2 つのノードを持つ Always On 可用性グループを設定します。この構成については、このドキュメントのマルチクラウド データベース移行アーキテクチャですでに説明しています。

次の表は、このチュートリアルで設定するノードと IP アドレスの概要を示しています。データベース VM ごとに、プライマリ IP アドレスとは別に 2 つの IP アドレスを割り振ります。1 つは Windows Server フェイルオーバー クラスタ(WSFC)用、もう 1 つは可用性グループ リスナー用です。

プロバイダ インスタンス プライマリ IP WSFC と可用性グループ リスナーの IP WSFC 可用性グループ
AWS cluster-sql1 192.168.1.4 192.168.1.5
192.168.1.6
Name: cluster-dbclus Name: cluster-ag
Listener: ag-listener
Google Cloud cluster-sql2 10.1.1.4 10.1.1.5
10.1.1.6
プロバイダ インスタンス プライマリ IP -
AWS dc-windows 192.168.1.100 Domain controller

この手順では、これらの名前と IP アドレスを例として使用します。独自の名前と IP アドレスを使用する場合は、手順のサンプル値を置き換えてください。

AWS の前提条件

AWS では、ドメイン コントローラを実行する仮想マシンと SQL Server を実行する仮想マシンの 2 つが必要になります。このチュートリアルで例として使用されるドメイン コントローラの構成は次のとおりです。

Domain                    : dbeng.com
Domain controller         : Name: dc-windows
                            Private IP: 192.168.1.100
VPC Subnet                : 192.168.1.0/24
SQL Server service account: dbeng\sql_service

このチュートリアルで例として使用される SQL Server VM は、Amazon EC2 の Windows Active Directory ドメインの一部です。サーバーには、WSFC と可用性グループ リスナーで使用される 2 つのセカンダリ IP アドレスがあります。SQL Server VM の構成は次のとおりです。

VM Instance : Name: cluster-sql1
              Private IP: 192.168.1.4
              Secondary Private IPs: 192.168.1.5, 192.168.1.6
VPC Subnet  : 192.168.1.0/24

SQL Server サービス アカウントとして、サービス アカウント NT SERVICE\MSSQLSERVER を使用できます。Always On 可用性グループのセットアップ中に、ドメイン アカウントではなくマシン アカウント(dbeng\cluster-sql1$dbeng\cluster-sql2$)へのアクセスを許可します。次のセクションでは、可用性グループを構成するコマンドについて説明します。

AWS と Google Cloud 間の接続の前提条件

AWS プロジェクトを Google Cloud プロジェクトに接続するには、次のネットワーク接続を設定します。

  1. それぞれのプロジェクトで Google Virtual Private Cloud と AWS VPC を設定し、これらの VPC 間の VPN を構成します。Google Cloud と AWS の間での VPN の設定方法については、マルチクラウド VPN とマルチゾーン サブネットワーク - マルチクラウド データベース デプロイ用のネットワーク設定をご覧ください。
  2. Google Cloud Shell で、SQL Server インスタンスを作成する Cloud プロジェクトにサブネットを作成します。すでにサブネットがある場合はそれを使用できますが、次の手順でファイアウォール ルールを設定してください。

    gcloud compute networks create demo-vpc --subnet-mode custom
    
    gcloud compute networks subnets create demo-subnet1 \
      --network demo-vpc --region us-east4 --range 10.1.1.0/24
    

    このチュートリアルでは、次の値を使用します。

    • VPC: demo-vpc
    • サブネット: demo-subnet1; 10.1.1.0/24

    サブネットは、Google Cloud コンソールの [VPC ネットワーク] ページに表示されます。

  3. Google Cloud プロジェクトで、ファイアウォールを作成して、Google Cloud サブネットと AWS サブネット間のすべてのトラフィックを許可します。

    gcloud compute firewall-rules create allow-vpn-ports \
      --network demo-vpc --allow tcp:1-65535,udp:1-65535,icmp \
      --source-ranges 10.1.1.0/24,192.168.1.0/24
    

    ファイアウォール ルールは、Google Cloud コンソールの [ファイアウォール ポリシー] ページに表示されます。

  4. 次のスクリーンショットに示すように、AWS プロジェクトで、セキュリティ グループにファイアウォール ルールを作成し、Google Cloud サブネットと AWS サブネット間のすべてのトラフィックを許可します。

    AWS の上り(受信)ルールは、すべてのトラフィック、すべてのプロトコル、すべてのポート範囲を許可するように構成されています。

    本番環境では、必要な TCP / UDP ポートのみを開くことを検討してください。必要なポートのみを開くことで、有害な可能性のあるトラフィックが制限され、必要最小限の原則に従うことができます。

Google Cloud で Always On 可用性グループのインスタンスを作成する

このチュートリアルは、次の Microsoft SQL Server のエディションと機能に対応しています。

  • エディション:
    • Microsoft SQL Server 2016 Enterprise Edition
    • Microsoft SQL Server 2017 Enterprise Edition
    • Microsoft SQL Server 2019 Enterprise Edition
    • Microsoft SQL Server 2022 Enterprise Edition
    • Microsoft SQL Server 2016 Standard Edition
    • Microsoft SQL Server 2017 Standard Edition
    • Microsoft SQL Server 2019 Standard Edition
    • Microsoft SQL Server 2022 Standard Edition
  • 機能: Always On 可用性グループ

次の手順では、Microsoft SQL Server 2019 Enterprise Edition のイメージ sql-ent-2019-win-2019 を使用します。Microsoft SQL Server 2017、2016、2022 Enterprise Editions をインストールする場合は、代わりに sql-ent-2017-win-2019sql-ent-2016-win-2019sql-ent-2022-win-2019 をそれぞれ使用します。すべてのイメージの一覧については、Compute Engine のオペレーティング システムの詳細ページをご覧ください。

次の手順では、Google Cloud で可用性グループ用の SQL Server インスタンスを作成します。このインスタンスは、次の IP アドレス構成とエイリアス IP アドレスを使用します。

VM Instance: Name: cluster-sql2
             Private IP: 10.1.1.4
             Secondary Private IPs: 10.1.1.5, 10.1.1.6

パブリック SQL Server イメージから cluster-sql2 という名前のインスタンスを、200 GB のブートディスク サイズ、n1-highmem-4 マシンタイプで作成します。通常、SQL Server インスタンスではドメイン コントローラのインスタンスよりも多くのコンピューティング リソースが必要になります。後でさらにコンピューティング リソースが必要になった場合、それらのインスタンスのマシンタイプを変更できます。さらにストレージ スペースが必要になった場合、ディスクを追加するか永続ブートディスクのサイズを変更します。より大規模な可用性グループでは、複数のインスタンスを作成できます。

この手順には、インスタンスの作成時に Microsoft PowerShell コマンドを実行してフェイルオーバー クラスタリング機能をインストールする --metadata sysprep-specialize-script-ps1 フラグも含まれています。

  1. Cloud Shell で、AWS と同じオペレーティング システム バージョンを使用する SQL Server インスタンスを Google Cloud に作成します。

    gcloud compute instances create cluster-sql2 --machine-type n1-highmem-4 \
      --boot-disk-type pd-ssd --boot-disk-size 200GB \
      --image-project windows-sql-cloud --image-family sql-ent-2019-win-2019 \
      --zone us-east4-a \
      --network-interface "subnet=demo-subnet1,private-network-ip=10.1.1.4,aliases=10.1.1.5;10.1.1.6" \
      --can-ip-forward \
      --metadata sysprep-specialize-script-ps1="Install-WindowsFeature Failover-Clustering -IncludeManagementTools;"
    
  2. インスタンスに接続する前に、Windows ユーザー名とパスワードを設定します。

  3. ノートパソコンからリモート デスクトップ プロトコル(RDP)を使用する場合は、インスタンスへのアクセスを許可するファイアウォール ルールを作成します

  4. RDP を使用して Google Cloud インスタンスに接続し、昇格した PowerShell(管理者として実行)を開きます。

  5. このチュートリアルでは、AWS のドメイン コントローラ(192.168.1.100)を使用するローカル DNS を構成し、Google Cloud で別の VM が作成されないようにします。本番環境ワークロードでは、VPN トンネルを介した認証を回避するために、Google Cloud のドメイン コントローラ(プライマリまたはセカンダリ)を使用することをおすすめします。

    昇格した PowerShell で、ドメイン コントローラ 192.168.1.100 に対して ping を実行できるはずです。

    ping 192.168.1.100
    

    ping が失敗する場合は、このドキュメントの接続の前提条件で説明したように、ファイアウォールと VPN トンネルが AWS と Google Cloud の間で正しく構成されていることを確認します。

  6. サーバーは元々 DHCP で設定されているため、静的 IP アドレスを使用するようにインスタンスを変更します。

    netsh interface ip set address name=Ethernet static 10.1.1.4 255.255.255.0 10.1.1.1 1
    

    上記のコマンドを実行すると、接続が失われます。RDP で再接続します。

  7. AWS でドメイン コントローラを使用するようにローカル DNS を構成し、SQL Server のローカル ファイアウォール ポートを開きます。ファイアウォール ポートを開くと、SQL Server がリモート SQL Server に接続できるようになります。

    netsh interface ip set dns Ethernet static 192.168.1.100
    
    netsh advfirewall firewall add rule name="Open Port 5022 for Availability Groups" dir=in action=allow protocol=TCP localport=5022
    
    netsh advfirewall firewall add rule name="Open Port 1433 for SQL Server" dir=in action=allow protocol=TCP localport=1433
    
  8. インスタンスを Windows ドメインに追加します。

    Add-Computer -DomainName "dbeng.com" -Credential "dbeng.com\Administrator" -Restart -Force
    

    このコマンドは、ドメイン管理者の認証情報の入力を求めます。コマンドの実行が完了したら、インスタンスが再起動します。

    コマンドが実行されない場合は、管理者として実行していることを確認してください。

  9. dbeng\Administrator アカウントで、RDP を使用してインスタンスに再接続します。

  10. SQL Server サービス アカウントを設定します。

    1. SQL Server 2019 構成マネージャーを開きます。
    2. [SQL Server Services] タブで、[SQL Server(MSSQLSERVER)] を右クリックし、[Properties] をクリックします。
    3. dbeng\sql_service のアカウントとパスワードを設定します。
    4. SQL Server を再起動します。
  11. コンピュータ名と一致するように SQL Server インスタンスの名前を変更し、SQL Server を再起動します。

    Invoke-Sqlcmd -Query "EXEC sp_dropserver @@SERVERNAME, @droplogins='droplogins'"
    
    Invoke-Sqlcmd -Query "EXEC sp_addserver '$env:COMPUTERNAME', local"
    
    Stop-Service -Name "MSSQLServer" -Force
    
    Start-Service -Name "MSSQLServer"
    

次に、AWS でインスタンスを構成します。

AWS でインスタンスを構成する

このチュートリアルは、AWS ですでに以下のように構成されていることを前提としています。

  • SQL Server インスタンスが Active Directory ドメインの一部になっている。
  • ローカル DNS が正常に機能していて、Google Cloud のリモート サーバーの名前(cluster-sql2.dbeng.com))を IP アドレスに変換できる。
  • AWS と Google Cloud のサブネット間のファイアウォール ルールがオープンになっている。

AWS で cluster-sql1 を構成する手順は次のとおりです。

  1. RDP を使用して AWS インスタンス(cluster-sql1)に接続します。
  2. 昇格した PowerShell を開きます(管理者として実行)。
  3. Windows フェイルオーバー クラスタリングがまだインストールされていない場合は、インストールします。

    Install-WindowsFeature Failover-Clustering -IncludeManagementTools
    

    機能がまだインストールされていない場合、このコマンドで再起動するように求められます。再起動したら、次の手順に進みます。

  4. AWS で SQL Server インスタンスのローカル ファイアウォール ポートを開きます。

    netsh advfirewall firewall add rule name="Open Port 5022 for Availability Groups" dir=in action=allow protocol=TCP localport=5022
    
    netsh advfirewall firewall add rule name="Open Port 1433 for SQL Server" dir=in action=allow protocol=TCP localport=1433
    
    netsh advfirewall firewall add rule name="ICMP Allow incoming V4 echo request" protocol="icmpv4:8,any" dir=in action=allow
    
  5. コンピュータ名と一致するように SQL Server インスタンスの名前を変更し、SQL Server を再起動します。

    Invoke-Sqlcmd -Query "EXEC sp_dropserver @@SERVERNAME, @droplogins='droplogins'"
    
    Invoke-Sqlcmd -Query "EXEC sp_addserver '$env:COMPUTERNAME', local"
    
    Stop-Service -Name "MSSQLServer" -Force
    
    Start-Service -Name "MSSQLServer"
    
  6. リモート インスタンス名を使用している場合に、AWS のインスタンスが Google Cloud のインスタンスに接続できることを確認します。接続をテストするには、SQL Server への接続アクセスを許可したドメイン アカウントから次のコマンドを実行します。

    1. ネットワーク接続をテストします。

      ping -4 cluster-sql2.dbeng.com
      

      出力は次のようになります。

      RESULTS:
      Pinging cluster-sql2.dbeng.com [10.1.1.4] with 32 bytes of data:
      Reply from 10.1.1.4: bytes=32 time=3ms TTL=127
      Reply from 10.1.1.4: bytes=32 time=2ms TTL=127
      Reply from 10.1.1.4: bytes=32 time=2ms TTL=127
      Reply from 10.1.1.4: bytes=32 time=2ms TTL=127
      
    2. リモート サーバーへの Windows 認証をテストします。

      sqlcmd -E -S cluster-sql2.dbeng.com -Q "SELECT 'CONNECTED'"
      

      出力は次のようになります。

      RESULTS:
      --------------------------------------------------------------------------
      CONNECTED
      
      (1 rows affected)
      

    接続できない場合は、DNS が適切に機能し、AWS と Google Cloud のサブネット間でファイアウォール ルールが開いていることを確認します。

Google Cloud インスタンスを可用性グループに加えられることを確認する。

  1. RDP(cluster-sql2)で、dbeng\Administrator アカウントを使用して Google Cloud インスタンスに接続します。
  2. 昇格した PowerShell を開きます(管理者として実行)。
  3. インスタンス名を使用している場合に、Google Cloud のインスタンスが AWS のインスタンスに接続できることを確認します。接続をテストするには、SQL Server への接続アクセスを許可したドメイン アカウントから次のコマンドを実行します。

    1. ネットワーク接続をテストします。

      ping -4 cluster-sql1.dbeng.com
      

      出力は次のようになります。

      RESULTS:
      Pinging CLUSTER-SQL1.dbeng.com [192.168.1.4] with 32 bytes of data:
      Reply from 192.168.1.4: bytes=32 time=3ms TTL=127
      Reply from 192.168.1.4: bytes=32 time=2ms TTL=127
      Reply from 192.168.1.4: bytes=32 time=3ms TTL=127
      Reply from 192.168.1.4: bytes=32 time=2ms TTL=127
      
    2. リモート サーバーへの Windows 認証をテストします。

      sqlcmd -E -S cluster-sql1 -Q "SELECT 'CONNECTED'"
      

      出力は次のようになります。

      RESULTS:
      ------------------------------------------------------------
      CONNECTED
      
      (1 rows affected)
      

      接続できない場合は、DNS が適切に機能し、AWS と Google Cloud のサブネット間でファイアウォール ルールが開いていることを確認します。

  4. C:\SQLDataC:\SQLLog にフォルダを作成します。これらのフォルダはデータベースのデータとログファイルに使用します。

    New-Item "C:\SQLData" –type directory
    New-Item "C:\SQLLog" –type directory
    
  5. C:\SQLBackup にフォルダを作成し、\\cluster-sql2\SQLBackup に Windows 共有を作成して、AWS インスタンスからバックアップを転送します。両方のサーバーで利用可能な他のネットワーク共有を使用できます。

    New-Item "C:\SQLBackup" –type directory
    New-SmbShare -Name "SQLBackup" -Path "C:\SQLBackup" -FullAccess
    "dbeng.com\cluster-sql1$","dbeng.com\cluster-sql2$","NT
    SERVICE\MSSQLSERVER","authenticated users","dbeng.com\sql_service"
    

これで、可用性グループ用にインスタンスの準備が整いました。インスタンスが 2 つしかないので、次のセクションでファイル共有監視を構成して、タイブレークのための投票を行い、クォーラムを達成します。

ファイル共有監視の作成

タイブレークのための投票を行ってフェイルオーバー シナリオのクォーラムを達成するために、監視として機能するファイル共有を作成します。このチュートリアルでは、ドメイン コントローラ VM にファイル共有監視を作成します。本番環境では、Active Directory ドメイン内のサーバーにファイル共有監視を作成します。

  1. dbeng\Administrator アカウントで、RDP を使用してドメイン コントローラ VM(dc-windows)に接続します。
  2. 昇格した PowerShell を開きます(管理者として実行)。
  3. 監視フォルダを作成します。

    New-Item "C:\QWitness" –type directory
    
  4. フォルダを共有します。

    New-SmbShare -Name "QWitness" -Path "C:\QWitness" -Description "SQL File Share Witness" -FullAccess "dbeng.com\Administrator", "dbeng.com\cluster-sql1$", "dbeng.com\cluster-sql2$"
    
  5. dbeng.com\Administrator で、RDP を使用して cluster-sql1cluster-sql2 の両方に接続します。

  6. 両方のサーバーから共有ディレクトリにアクセスできることを確認します。

    dir \\dc-windows\QWitness
    

    共有ディレクトリにアクセスできない場合は、ノードのネットワーク接続を変更して、WINS サーバーがドメイン サーバーと一致するように設定してみてください。ネットワーク接続の変更には数秒かかることがあります。次のスクリーンショットは、更新された WINS 設定を示しています。

    [Advanced TCP / IP Settings] の更新された WINS アドレス設定。

これで、可用性グループのためのあらゆる準備ができました。次に、フェイルオーバー クラスタリングを構成します。

フェイルオーバー クラスタリングの構成

このセクションでは、WSFC を構成し、両方のインスタンスで Always On 高可用性を有効にします。AWS のインスタンスから次のすべての構成コマンドを実行します。

  1. RDP を使用して AWS インスタンス(cluster-sql1)に接続します。
  2. 昇格した PowerShell を開きます(管理者として実行)。
  3. クラスタ環境に対応する変数を設定します。この例では、以下の変数を設定します。

    $node1 = "cluster-sql1.dbeng.com"
    $node2 = "cluster-sql2.dbeng.com"
    $nameWSFC = "cluster-dbclus" #Name of cluster
    $ipWSFC1 = "192.168.1.5" #IP address of cluster in subnet 1 (AWS)
    $ipWSFC2 = "10.1.1.5"    #IP address of cluster in subnet 2 (Google Cloud)
    
  4. フェイルオーバー クラスタを作成します(このコマンドの実行には時間がかかることがあります)。

    New-Cluster -Name $nameWSFC -Node $node1, $node2 -NoStorage -StaticAddress $ipWSFC1, $ipWSFC2
    
    Set-ClusterQuorum -FileShareWitness \\dc-windows\QWitness
    
  5. ノード 1 で Always On 高可用性を有効にします。Always On をまだ有効にしていない場合、これらのコマンドを実行すると、SQL Server が強制的に再起動されます。

    Enable-SqlAlwaysOn -ServerInstance $node1 -Force
    
  6. ノード 2 で Always On 高可用性を有効にします。これらのコマンドは、SQL Always On を有効にする前に SQL Server サービスを停止するため、次のようなエラーは無視できます: Enable-SqlAlwaysOn : StopService failed for Service 'MSSQLSERVER'

    Get-Service -ComputerName $node2 -Name "MSSQLServer" | Stop-Service -Force
    
    Enable-SqlAlwaysOn -ServerInstance $node2 -Force
    
    Get-Service -ComputerName $node2 -Name "MSSQLServer" | Start-Service
    
  7. C:\SQLDataC:\SQLLog にフォルダを作成します。これらのフォルダは TestDB データベースのデータとログファイルに使用します。このフォルダ構造のデータベースがサーバー上にすでに存在する場合は、この手順を省略できます。不明な場合は、コマンドを実行して、既存フォルダに関するエラー メッセージを無視します。

    New-Item "C:\SQLData" –type directory
    New-Item "C:\SQLLog" –type directory
    

これで、フェイルオーバー クラスタ マネージャーの準備が整いました。次に、可用性グループを作成します。

可用性グループの作成

このセクションでは、AWS でテスト データベース(cluster-sql1)を作成し、新しい可用性グループで機能するように構成します。または、可用性グループに既存のデータベースを指定することもできます。

  1. RDP を使用して AWS インスタンス(cluster-sql1)に接続します。
  2. 昇格した PowerShell を開きます(管理者として実行)。
  3. データベースのバックアップを保存するフォルダを C:\SQLBackup に作成します。バックアップは、新しいデータベースに可用性グループをセットアップする前に行う必要があります。

    New-Item "C:\SQLBackup" –type directory
    
  4. まだデータベースが構成されていない場合は、SQL Server Management Studio を実行し、AWS インスタンス(cluster-sql1)にテスト データベースを作成します。

    CREATE DATABASE TestDB
    ON PRIMARY (NAME = 'TestDB_Data', FILENAME='C:\SQLData\TestDB_Data.mdf', SIZE = 256MB, MAXSIZE = UNLIMITED, FILEGROWTH = 256MB )
    LOG ON (NAME = 'TestDB_Log', FILENAME='C:\SQLLog\TestDB_Log.ldf', SIZE = 256MB, MAXSIZE = UNLIMITED, FILEGROWTH = 256MB )
    GO
    
    USE [TestDB]
    Exec dbo.sp_changedbowner @loginame = 'sa', @map = false;
    ALTER DATABASE [TestDB] SET RECOVERY FULL;
    GO
    
    BACKUP DATABASE TestDB to disk = 'C:\SQLBackup\TestDB-backup.bak' WITH INIT
    GO
    
  5. Microsoft SQL Server Management Studio で、[Query] > [SQLCMD Mode] を選択します。

    SQL Server Management Studio には、可用性グループを作成するためのウィザードが用意されています。このチュートリアルでは、SQL コマンドを使用するため、さまざまなクラウド プロバイダ間で接続する際に発生する可能性のある問題を簡単にデバッグできます。必要に応じて、可用性グループ ウィザードを実行し、後の手順にスキップして可用性グループが同期していることを確認できます

  6. SQLCMD モードで以下のクエリを実行します。既存のデータベースを使用している場合は、TestDB をデータベースの名前に置き換えます。

    1. 最初のノードにエンドポイントを作成し、そのエンドポイントに権限を付与します。

      :Connect CLUSTER-SQL1
      IF NOT EXISTS (SELECT state FROM sys.endpoints WHERE name = N'Hadr_endpoint')
      BEGIN
        CREATE ENDPOINT [Hadr_endpoint]
        AS TCP (LISTENER_PORT = 5022)
        FOR DATA_MIRRORING (ROLE = WITNESS, ENCRYPTION = REQUIRED ALGORITHM AES)
      END
      GO
      
      IF (SELECT state FROM sys.endpoints WHERE name = N'Hadr_endpoint') <> 0
      BEGIN
        ALTER ENDPOINT [Hadr_endpoint] STATE = STARTED
      END
      GO
      
      use [master]
      GO
      
      IF SUSER_ID('DBENG\sql_service') IS NULL
        CREATE LOGIN [DBENG\sql_service] FROM WINDOWS
      GO
      
      GRANT CONNECT ON ENDPOINT::[Hadr_endpoint] TO [DBENG\sql_service]
      GO
      
    2. 最初のノードで AlwaysOn_health 拡張イベント セッションを有効にします。可用性グループには、拡張イベント セッションが必要です。

      :Connect CLUSTER-SQL1
      IF EXISTS(SELECT * FROM sys.server_event_sessions WHERE name='AlwaysOn_health')
      BEGIN
        ALTER EVENT SESSION [AlwaysOn_health] ON SERVER WITH (STARTUP_STATE=ON);
      END
      IF NOT EXISTS(SELECT * FROM sys.dm_xe_sessions WHERE name='AlwaysOn_health')
      BEGIN
        ALTER EVENT SESSION [AlwaysOn_health] ON SERVER STATE=START;
      END
      GO
      
    3. 2 番目のノードにエンドポイントを作成し、そのエンドポイントに権限を付与します。

      :Connect CLUSTER-SQL2
      IF NOT EXISTS (SELECT state FROM sys.endpoints WHERE name = N'Hadr_endpoint')
      BEGIN
        CREATE ENDPOINT [Hadr_endpoint]
          AS TCP (LISTENER_PORT = 5022)
          FOR DATA_MIRRORING (ROLE = WITNESS, ENCRYPTION = REQUIRED ALGORITHM AES)
      END
      GO
      
      IF (SELECT state FROM sys.endpoints WHERE name = N'Hadr_endpoint') <> 0
      BEGIN
        ALTER ENDPOINT [Hadr_endpoint] STATE = STARTED
      END
      GO
      
      use [master]
      GO
      
      IF SUSER_ID('DBENG\sql_service') IS NULL
        CREATE LOGIN [DBENG\sql_service] FROM WINDOWS
      GO
      
      GRANT CONNECT ON ENDPOINT::[Hadr_endpoint] TO [DBENG\sql_service]
      GO
      
    4. 2 番目のノードで AlwaysOn_health 拡張イベント セッションを有効にします。可用性グループには、拡張イベント セッションが必要です。

      :Connect CLUSTER-SQL2
      IF EXISTS(SELECT * FROM sys.server_event_sessions WHERE name='AlwaysOn_health')
      BEGIN
        ALTER EVENT SESSION [AlwaysOn_health] ON SERVER WITH (STARTUP_STATE=ON);
      END
      IF NOT EXISTS(SELECT * FROM sys.dm_xe_sessions WHERE name='AlwaysOn_health')
      BEGIN
        ALTER EVENT SESSION [AlwaysOn_health] ON SERVER STATE=START;
      END
      GO
      
    5. 最初のノードで可用性グループを作成します。

      :Connect CLUSTER-SQL1
      USE [master]
      GO
      
      --DROP AVAILABILITY GROUP [cluster-ag];
      GO
      
      CREATE AVAILABILITY GROUP [cluster-ag]
      WITH (AUTOMATED_BACKUP_PREFERENCE = SECONDARY,
      DB_FAILOVER = OFF,
      DTC_SUPPORT = NONE)
      FOR DATABASE [TestDB]
      REPLICA ON N'CLUSTER-SQL1' WITH (ENDPOINT_URL = N'TCP://CLUSTER-SQL1.dbeng.com:5022', FAILOVER_MODE = MANUAL, AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, BACKUP_PRIORITY = 50, SEEDING_MODE = MANUAL),
        N'CLUSTER-SQL2' WITH (ENDPOINT_URL = N'TCP://cluster-sql2.dbeng.com:5022', FAILOVER_MODE = MANUAL, AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, BACKUP_PRIORITY = 50, SEEDING_MODE = MANUAL);
      GO
      
    6. 2 番目のノードを新しく作成された可用性グループに参加させます。

      :Connect CLUSTER-SQL2
      ALTER AVAILABILITY GROUP [cluster-ag] JOIN;
      GO
      
    7. 最初のノードでデータベースのバックアップを作成します。

      :Connect CLUSTER-SQL1
      BACKUP DATABASE [TestDB] TO DISK = N'\\CLUSTER-SQL2\SQLBackup\TestDB.bak' WITH COPY_ONLY, FORMAT, INIT, SKIP, REWIND, NOUNLOAD, COMPRESSION, STATS = 5
      GO
      
    8. 2 番目のノードでデータベースのバックアップを復元します。

      :Connect CLUSTER-SQL2
      RESTORE DATABASE [TestDB] FROM DISK = N'\\CLUSTER-SQL2\SQLBackup\TestDB.bak' WITH NORECOVERY, NOUNLOAD, STATS = 5
      GO
      
    9. 最初のノードでトランザクション ログのバックアップを作成します。

      :Connect CLUSTER-SQL1
      BACKUP LOG [TestDB] TO DISK = N'\\CLUSTER-SQL2\SQLBackup\TestDB.trn' WITH NOFORMAT, INIT, NOSKIP, REWIND, NOUNLOAD, COMPRESSION, STATS = 5
      GO
      
    10. 2 番目のノードでトランザクション ログのバックアップを復元します。

      :Connect CLUSTER-SQL2
      RESTORE LOG [TestDB] FROM  DISK = N'\\CLUSTER-SQL2\SQLBackup\TestDB.trn' WITH NORECOVERY, NOUNLOAD, STATS = 5
      GO
      
  7. 同期にエラーがないことを確認するには、次のクエリを実行して、列 connected_state_desc の値が CONNECTED であることを確認します。

    :Connect CLUSTER-SQL2
    select r.replica_server_name, r.endpoint_url,
           rs.connected_state_desc, rs.last_connect_error_description,
           rs.last_connect_error_number, rs.last_connect_error_timestamp
     from sys.dm_hadr_availability_replica_states rs
      join sys.availability_replicas r
       on rs.replica_id=r.replica_id
     where rs.is_local=1
    
    • connected_state_desc にエラー メッセージ An error occurred while receiving data: '24(The program issued a command but the command length is incorrect)' がある場合は、次のコマンドを実行してエラーの解消を試みます。

      :Connect CLUSTER-SQL1
      IF SUSER_ID('DBENG\CLUSTER-SQL2$') IS NULL
         CREATE LOGIN [DBENG\CLUSTER-SQL2$] FROM WINDOWS
      GO
      
      GRANT CONNECT ON ENDPOINT::[Hadr_endpoint] TO [DBENG\CLUSTER-SQL2$]
      GO
      
      :Connect CLUSTER-SQL2
      IF SUSER_ID('DBENG\CLUSTER-SQL1$') IS NULL
        CREATE LOGIN [DBENG\CLUSTER-SQL1$] FROM WINDOWS
      GO
      
      GRANT CONNECT ON ENDPOINT::[Hadr_endpoint] TO [DBENG\CLUSTER-SQL1$]
      GO
      

      上のクエリを再実行して、同期エラーが発生しないようにします。エラーが解消されるまで数分かかることがあります。エラーが続く場合は、Always On 可用性グループの構成(SQL Server)のトラブルシューティングをご覧ください。

  8. 可用性グループの設定を完了します。

    :Connect CLUSTER-SQL2
    ALTER DATABASE [TestDB] SET HADR AVAILABILITY GROUP = [cluster-ag]
    GO
    
    ALTER DATABASE [TestDB] SET HADR RESUME;
    GO
    
  9. 可用性グループが同期していることを確認する:

    1. SQL Server Management Studio の [Always On High Availability] > [Availability Groups] で可用性グループを右クリックし、[Show Dashboard] を選択します。

    2. 次のスクリーンショットに示すように、プライマリの同期状態が [Synchronized] で、セカンダリの同期状態が [Synchronizing] であることを確認します。

      SQL Server Management Studio に、可用性グループの同期状態が表示されます。

  10. リスナーを追加するには、[Always On High Availability] > [Availability Groups] > [cluster-ag (Primary)] > [Availability Group Listeners] で、可用性グループの名前を右クリックし、[Add Listener] を選択します。

  11. [New Availability Group Listener] ダイアログで、リスナーに次のパラメータを指定します。

    • リスナーの DNS 名: ag-listener
    • ポート: 1433
    • ネットワーク モード: Static IP
  12. 2 つのサブネットと IP アドレス フィールドを追加します。この例では、以下のサブネットと IP アドレスのペアを使用します。これらのペアは、SQL Service インスタンス VM のプライマリ IP アドレスに加えて作成した IP アドレスです。

    1. 最初のペアに次の値を入力します。
      • サブネット: 192.168.1.0/24
      • IPv4 アドレス: 192.168.1.6
    2. 2 番目のペアに次の値を入力します。
      • サブネット: 10.1.1.0/24
      • IPv4 アドレス: 10.1.1.6
  13. サブネットと IP アドレスのペアの追加が完了したら、[OK] をクリックします。

  14. インスタンスの名前ではなく、SQL Server データベースの名前として ag-listener.dbeng.com を使用して SQL Server に接続します。この接続は、現在アクティブなインスタンスを指します。

    1. [Object Explorer] で [Connect] をクリックし、[Database Engine] を選択します。
    2. [Connect to Server] ダイアログの [サーバー名] フィールドに、リスナーの名前 ag-listener.dbeng.com を入力します。
    3. サーバー名を追加したら、[Connect] をクリックします。次のスクリーンショットのように、[Object Explorer] で新しい接続を確認できます。

      オブジェクト エクスプローラには接続が表示されます。

    RDP を使用して cluster-sql2 に接続している場合は、オプションでこの手順を繰り返して接続を確立できます。

テストデータを追加する

このセクションでは、cluster-sql1 でテストテーブルとテストデータを TestDB データベースに追加し、データ レプリケーションを検証します。

  1. cluster-sql1Persons という名前のテーブルを作成します。

    :Connect CLUSTER-SQL1
    USE TestDB;
    CREATE TABLE Persons (
        PersonID int,
        LastName varchar(255),
        FirstName varchar(255),
        PRIMARY KEY (PersonID)
    );
    
  2. 以下の数行を挿入します。

    :Connect CLUSTER-SQL1
    USE TestDB;
    INSERT INTO Persons (PersonId, LastName, FirstName)
      VALUES (1, 'Velasquez', 'Ava');
    INSERT INTO Persons (PersonId, LastName, FirstName)
      VALUES (2, 'Delaxcrux', 'Paige');
    
  3. Enterprise Edition を使用している場合は、リードレプリカ(cluster-sql2)に対する読み取りアクセスを有効にして、レプリケーションが行われていることを確認します。Standard Edition は、リードレプリカに対する読み取り専用アクセスに対応していません。Standard Edition を使用している場合は、次のセクションに進んで Google Cloud へのカットオーバーを実行するをご覧ください。

    :Connect CLUSTER-SQL1
    ALTER AVAILABILITY GROUP [cluster-ag]
    MODIFY REPLICA ON N'CLUSTER-SQL2' WITH (SECONDARY_ROLE(ALLOW_CONNECTIONS = ALL))
    GO
    
  4. Enterprise Edition の場合、cluster-sql2 のテーブルにクエリを実行し、テーブル コンテンツが複製されたことを確認します。

    :Connect CLUSTER-SQL2
    SELECT * FROM TestDB.dbo.Persons;
    

データが cluster-sql1 から cluster-sql2 にレプリケートされたら、カットオーバーを実行します。レプリケーションのみを行う場合は、次のセクションをスキップし、カットオーバーやフォールバックを実行しないでください。レプリケーションの実行に使用していたリソースを保持しない場合は、このチュートリアルの最後にあるクリーンアップの手順を行って、料金が発生しないようにします。

Google Cloud へのカットオーバーを実行する

整合性のあるデータセットを実現するために、cluster-sql1 に書き込むクライアントを停止して、カットオーバーを実行する前にすべてのデータが cluster-sql2 に複製されるようにする必要があります。

整合性を保つため、すべてのデータを完全に複製する必要があります。このセクションでは、可用性モードを SYNCHRONOUS_COMMIT に変更することで、完全なデータ レプリケーションを実現します。この変更により、cluster-sql1cluster-sql2 への完全なレプリケーションが可能になります。

  1. 両方のノードの可用性モードを同期 commit に変更するには、cluster-sql1 で次の SQL コマンドを実行します。両方のノードを同期 commit に設定することが、データが失われないようにするための唯一の方法です。

    :Connect CLUSTER-SQL1
    ALTER AVAILABILITY GROUP [cluster-ag]
    MODIFY REPLICA ON N'CLUSTER-SQL1' WITH (AVAILABILITY_MODE = SYNCHRONOUS_COMMIT)
    GO
    
    ALTER AVAILABILITY GROUP [cluster-ag]
    MODIFY REPLICA ON N'CLUSTER-SQL2' WITH (AVAILABILITY_MODE = SYNCHRONOUS_COMMIT)
    GO
    
  2. これで、Cluster-sql2 をプライマリ ノードにする準備ができました。cluster-sql2 に接続してプライマリ ノードにします。

    :Connect CLUSTER-SQL2
    ALTER AVAILABILITY GROUP [cluster-ag] FAILOVER;
    GO
    
  3. 両方のノードで、可用性モードを非同期 commit に変更します。cluster-sql2 はプライマリ ノードであるため、cluster-sql2 で次の SQL コマンドを実行します。

    :Connect CLUSTER-SQL2
    ALTER AVAILABILITY GROUP [cluster-ag]
    MODIFY REPLICA ON N'CLUSTER-SQL1' WITH (AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT)
    GO
    
    ALTER AVAILABILITY GROUP [cluster-ag]
    MODIFY REPLICA ON N'CLUSTER-SQL2' WITH (AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT)
    GO
    

    これで、アプリケーションのメインノードとして cluster-sql2 を使用する準備ができました。cluster-sql1 は、非同期に複製されたセカンダリです。

  4. cluster-sql2 がプライマリ ノードになったので、cluster-sql2 のテーブルにクエリを実行して、テーブルのコンテンツが複製されたことを確認します。

    :Connect CLUSTER-SQL2
    SELECT * FROM TestDB.dbo.Persons;
    

    出力は、このチュートリアルの前半でテーブルに挿入したテストデータと一致します。

レプリケーションをさらに検証するには、新しいテーブルを作成し、新しいプライマリに単一の行を挿入します。テーブルとその行がセカンダリに表示される場合、レプリケーションは機能しています。

フォールバック

新しいプライマリを元のプライマリにフォールバックする必要性が生じることがあります。このチュートリアルの前半で Google Cloud へのカットオーバーを完了したときに、元のプライマリ(cluster-sql1)を新しいプライマリ(cluster-sql2)のセカンダリにしています。

フォールバックを完了するには、Google Cloud へのカットオーバーを実行するプロセスに従って、次の値を置き換えます。

  • 元のプライマリ(cluster-sql1)を新しいプライマリ(cluster-sql2)に置き換えます。
  • 元のセカンダリ(cluster-sql2)を新しいセカンダリ(cluster-sql1)に置き換えます。

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。

このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにする手順は次のとおりです。

Google Cloud でプロジェクトを削除する

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

AWS でプロジェクトを削除する

AWS でリソースを作成して使用したため、その後も費用が発生します。これ以上の料金が発生しないようにするには、AWS でリソースを削除してください。

次のステップ