SQL Server で分散トランザクションを実行する場合、MSDTC (Distributed Transaction Coordinator) を使用して実現を行います。
SQL Server on Linux の当初は MSDTC をサポートしていなかったのですが、SQL Server 2017 CU16 以降は、MSDTC がサポートされ、以下の情報の設定を実施することで SQL Server on Linux でも MSDTC を使用することができるようになりました。
SQL Server on Linux で MSDTC を動作させる際の関連情報をまとめておきたいと思います。
Contents
MSDTC を使用する際の初期設定と問題発生時に確認する情報
初期設定
SQL Server に対して、MSDTC を使用した分散トランザクションを実行するためには、以下の二つの環境の MSDTC が相互に連携される必要があります。
- 分散トランザクションを開始するコンピューター上の MSDTC
- 分散トランザクションに関連する SQL Server 上の MSDTC
この連携を可能にするためのS MSDTC の設定については、次の情報を参考にする機会が多いのではないでしょうか。
- MSDTCを動作させるために必要な設定について
- ファイアウォール経由で動作するように Microsoft 分散トランザクション コーディネーター (DTC) を構成する
- Windows の分散トランザクション コーディネーター サービスの新機能
- How It Works: SQL Server DTC (MSDTC and XA Transactions)
この設定をそれぞれの環境の MSDTC に対して実施することで、分散トランザクションが可能となります。
SQL Server on Linux の場合、コンポーネントサービスの MMC が使用できないため、上記の技術情報の中で設定として意識する必要があるのは、次の 2 点となります。
- TCP 135 / 動的ポート (49152 / 655535) のポートアクセスの許可
- SQL Server on Linux のドキュメントでは動的ポートは 51000 を使用していることが多いかと
- サーバー名で相互に通信できる
- hosts / DNS を使用して、サーバー名のみの指定で相互に通信が可能な状態となっている
- DNS を使用する場合は、同一のサフィックスでの名前解決を構成することになるのではないでしょうか
トラブルシューティングの関連情報
公式ドキュメント
MSDTC のトラブルシューティングの情報としては、BizTalk のドキュメントとなりますが次の情報が参考となります。
SQL Server on Linux の MSDTC は Windows 版の MSDTC とは異なる起動方法となっているため、上記のトラブルシューティングのすべてが該当するというわけではありませんが、ネットワークの通信要件と、サーバー名を使用した相互通信については同様の考え方となります。
Stack Overflow
SQL Server on Linux の MSDTC については、 Stack Ovrflow でも質問が上がっていますので、次の情報も参考となります。
- How to set up MSDTC with Dockerized SQL Server for Linux
- MSDTC configuration issues with SQL Server in Docker (Linux) and Windows Host
SQL Server on Linux の MSDTC
前述のとおり、SQL Server on Linux で MSDTC を使用する場合、Linux で Microsoft 分散トランザクション コーディネーター (MSDTC) を構成する方法 / SQL Server Linux コンテナーで分散トランザクションを使用する方法 の方法で機能の有効化を行います。
Windows の環境では、MSDTC は msdtc.exe が独立したプロセスとして起動します。
SQL Server on Linux (Docker での実行含む) での実行時には、msdtc.exe が独立したプロセスとして起動するのではなく、SQL Server のプロセスの起動と同じ方法で実行されており、ライブラリ OS 上で実行されています。(MSDTC に必要なファイルは system.common.sfp にパックされています)
SQL Server on Linux で MSDTC が起動した状態では、必要となるポートをリスニングしているプロセスとしては sqlservr となります。
上記の情報は次のコマンドで Docker コンテナーで MSDTC を起動して確認した情報となります。(現在の Docker の SQL Serer は非 root コンテナーで起動されますが調査目的のため root 化しています)
docker run --name sql1 --hostname sql1 --user 0:0 -e 'ACCEPT_EULA=Y' -e 'MSSQL_SA_PASSWORD=<強固なパスワード>' -e 'MSSQL_RPC_PORT=135' -e 'MSSQL_DTC_TCP_PORT=51000' -p 1433:1433 -p 135:135 -p 51000:51000 -d mcr.microsoft.com/mssql/server:2022-latest
SQL Server on Linux の MSDTC は Linux 向けの MSDTC を実行しているのではなく、Linux 上で Windows の MSDTC を実行するというアプローチで実行が行われています。
そのため、プロセスとして msdtc のプロセスがユーザーに見える形で起動しているのではなく、sqlservr のプロセス内に含まれる形で起動しているため、MSDTC の設定については、環境変数 / mssql-conf を介して設定を行うことになります。
上記のコマンドでは、TCP 135 / 51000 を MSDTC で使用するポートとして指定していますが、51000 については初期状態ではリスニングされていません。
MSDTC にによる初回アクセスが行われた際に、TCP 51000 のリスニングが開始されるため、MSDTC に関するポートは初期は TCP 135 のみリスニングしている状態となりますので、servertcpport (MSSQL_DTC_TCP_PORT) で指定したポートが初期状態でリスニングしていないのは想定された動作となります。