go-mssqldbドライバーはAzure SQL Database、Azure SQL Managed Instance、SQLデータベースへの接続をMicrosoft Fabricサポートしています。 この記事では、オンプレミスのSQL Serverとは異なるAzure固有の設定、認証、接続制限、トラブルシューティングについて説明します。
Azure SQL Database に接続する
Azure SQL Databaseはデフォルトで暗号化接続が必要です。
encrypt=trueとTrustServerCertificate=falseを明示的に指定し、接続がTLSを使用しサーバー証明書を検証するようにしてください:
db, err := sql.Open("sqlserver",
"sqlserver://<user>:<password>@<server>.database.windows.net?database=<database>&encrypt=true&TrustServerCertificate=false")
if err != nil {
panic(err)
}
Note
encryptを省略すると、ドライバーは自動的にAzure固有のTLS設定を追加しません。
encrypt=true&TrustServerCertificate=falseはAzure SQL接続線に留めておけ。
パスワードレス認証(推奨)
Microsoft Entra ID認証は接続文字列からパスワードを除去します。
ActiveDirectoryDefault 環境に最適な資格を自動的に選択し、開発に便利になります:
import (
"database/sql"
"log"
_ "github.com/microsoft/go-mssqldb/azuread"
)
func main() {
db, err := sql.Open("azuresql",
"sqlserver://<server>.database.windows.net?database=<database>&fedauth=ActiveDirectoryDefault&encrypt=true&TrustServerCertificate=false")
if err != nil {
log.Fatal(err)
}
defer db.Close()
}
Important
ActiveDirectoryDefault 開発には便利ですが、複数の認証情報源を探査するため接続遅延が増加する可能性があります。 本番サービスの場合は、 ActiveDirectoryManagedIdentity や ActiveDirectoryServicePrincipalのような明示的な方法を好む。
ActiveDirectoryDefaultが認証情報を解決する方法
ActiveDirectoryDefault 以下の認証情報ソースを順番に試し、最初に成功したものを使用します。
| Order | 資格情報の出典 | 典型的な環境 |
|---|---|---|
| 1 | 環境変数(AZURE_CLIENT_ID、 AZURE_TENANT_ID、 AZURE_CLIENT_SECRET) |
CI/CDパイプライン、Dockerコンテナ |
| 2 | ワークロード識別子 | Azure Workload Identity を使用する Kubernetes Pod |
| 3 | マネージド ID | Azure VMs, App Service, Container Apps, Azure Functions |
| 4 | Azure CLI(az login) |
ローカル開発 |
| 5 | Azure Developer CLI(azd auth login) |
ローカル開発 |
この認証情報チェーンは開発時に便利 ActiveDirectoryDefault しますが、逐次的なプローブは新しい接続ごとに遅延を増やします。 本番環境では、ドライバーが不要なチェックをスキップできるように、正確な認証方法(例: ActiveDirectoryManagedIdentity)を指定します。
本番環境のためのマネージドアイデンティティ(推奨)
Azureでホストされるアプリケーション(App Service、コンテナアプリ、Azure Functions、またはAzure VMなど)は、明示的なfedauth値を持つマネージドIDを使用するべきです。 この方法は認証チェーンのオーバーヘッドを回避し、環境変数やCLI状態への依存を排除します。
システム割り当てマネージド ID:
sqlserver://<server>.database.windows.net?database=<database>&fedauth=ActiveDirectoryManagedIdentity&encrypt=true&TrustServerCertificate=false
ユーザー割り当てマネージド ID(クライアント ID を指定):
sqlserver://<server>.database.windows.net?database=<database>&fedauth=ActiveDirectoryManagedIdentity&user id=<client-id>&encrypt=true&TrustServerCertificate=false
データベース内で識別情報へのアクセスを付与します
AzureリソースでマネージドIDを設定した後、含まれたデータベースユーザーを作成します。
CREATE USER [my-app-identity] FROM EXTERNAL PROVIDER;
ALTER ROLE db_datareader ADD MEMBER [my-app-identity];
ALTER ROLE db_datawriter ADD MEMBER [my-app-identity];
システムに割り当てられたアイデンティティについては、Azureリソース名を使用します。 ユーザー割り当てのアイデンティティについては、アイデンティティ名を使いましょう。
自動化のためのサービスプリンシパル
CI/CDパイプラインやサービス間認証の場合:
sqlserver://<server>.database.windows.net?database=<database>&fedauth=ActiveDirectoryServicePrincipal&user id=<client-id>&password=<client-secret>&encrypt=true&TrustServerCertificate=false
すべての認証情報タイプについては、Microsoft Entra ID認証を参照してください。
Azureファイアウォールの設定
Azure SQL Databaseはサーバーレベルのファイアウォールを使用しています。 クライアントのパブリックIPアドレスを許可するか、プライベートエンドポイントを使う必要があります。
エラー:サーバーを開けません
このエラーメッセージは、AzureファイアウォールがクライアントのIPアドレスをブロックしていることを示しています:
mssql: login error: Cannot open server '<server>' requested by the login.
Client with IP address '<client-ip>' is not allowed to access the server.
ソリューション:
- Azureポータルにファイアウォールルールを追加してください:SQL Server>Networking>ファイアウォールルールを追加してください。
- アプリケーションがAzure上で動作している場合は、Azureのサービスとリソースがこのサーバーにアクセスすることを許可してください。
- プライベート接続の場合は 、プライベートエンドポイントを設定してください。
エラー:接続タイムアウト
もし接続がタイムアウトしても明確なエラーが出ない場合は、ファイアウォールが静かに接続をブロックしている可能性が高いです。 まずファイアウォールのルールを確認してください。
サービス階層別の接続制限
Azure SQL Databaseはサービス階層に基づいてデータベースごとの接続制限を強制します。 制限を超えると、新しい接続で認証に失敗します。 完全なリミットテーブルについては、 DTU単一データベースリソースリミ ットおよび vCore単一データベースリソースリミットを参照してください。
MaxOpenConnsは自分のティアに合わせて設定します
Azure SQLティアの接続上限より低い値にMaxOpenConnsを設定してください:
// Example for S2 tier (60 max workers).
// Leave headroom for Azure management connections and other clients.
db.SetMaxOpenConns(20)
db.SetMaxIdleConns(10)
db.SetConnMaxLifetime(5 * time.Minute)
Tip
複数のアプリケーションが同じデータベースを共有している場合、接続制限をすべてのアプリケーションで分割します。 例えば、3つのサービスがS2データベースを共有している場合(最大60人のワーカー)、各サービスに15〜20の接続を割り当てます。
Azure SQL のスロットリングに対処する
Azure SQL Databaseは、データベースがリソース制限(CPU、IO、メモリ、セッション数)に近づくと接続やクエリを制限できます。 スロットリングは、特定のエラー番号という形で現れます。
よくあるスロットリングエラー
| エラー番号 | メッセージ パターン | 原因 |
|---|---|---|
| 10928 | Resource ID: %d. The %s limit for the database is %d and has been reached. |
セッションまたはワーカーの上限に達しました。 |
| 10929 | Resource ID: %d. The %s minimum guarantee is %d, maximum limit is %d. |
リソースガバナーのスロットリング。 |
| 40501 | The service is currently busy. |
一般的なスロットリング。 再試行してください。 |
| 40544 | The database has reached its size quota. |
データベースサイズ制限に達しました。 再挑戦する前に容量を増やすか空きスペースを広げてください。 |
| 40549 | Session is terminated because you have a long-running transaction. |
取引は期限を超えました。 |
| 40550 | Session is terminated because of too many locks. |
過剰なロック取得。 |
| 40551 | Session is terminated because of excessive tempdb usage. |
tempdbの過剰使用。 |
| 40552 | Session is terminated because of excessive transaction log usage. |
トランザクションログの容量が超過しました。 |
| 40553 | Session is terminated because of excessive memory usage. |
過剰なメモリ消費。 |
| 40613 | Database '%.*ls' on server '%.*ls' is not currently available. |
データベースの移動や再構成。 |
| 49918 | Cannot process request. Not enough resources to process request. |
リソースの枯渇。 |
| 49919 | Cannot process create or update request. |
同時に作成・更新操作が多すぎます。 |
| 49920 | Cannot process request. Too many operations in progress. |
同時運用制限に達しました。 |
スロットリングされたリクエストを再試行する
前述の表のほとんどのAzure SQLのスロットリングおよび可用性エラーは一時的なものであり、指数的なバックオフで再試すべきです。 エラー 40544 は一時的なものではありません。 これはデータベースのサイズがノルマに達したため、データベースを拡大するかデータを削除しない限り操作は成功しません。
完全なリトライ実装については、「 エラー処理およびリトライパターン」を参照してください。
import (
"errors"
mssql "github.com/microsoft/go-mssqldb"
)
func isAzureThrottling(err error) bool {
var mssqlErr mssql.Error
if !errors.As(err, &mssqlErr) {
return false
}
switch mssqlErr.Number {
case 10928, 10929, 40501, 40549, 40550, 40551, 40552, 40553,
40613, 49918, 49919, 49920:
return true
}
return false
}
接続の回復力
Azure SQL Databaseは時折、更新、フェイルオーバー、ロードバランシングのためにサーバーを再設定します。 これらのイベントは既存の接続を切り落とし、 driver: bad connection エラーとして浮かび上がります。 プールを自動復旧するように設定してください:
db.SetConnMaxLifetime(5 * time.Minute) // Rotate connections so stale ones are replaced.
db.SetConnMaxIdleTime(2 * time.Minute) // Recycle before Azure gateway drops idle connections (30 min).
db.SetMaxIdleConns(10) // Keep warm connections for quick recovery.
Note
Azure SQLゲートウェイは約30分間アイドル状態の接続をクローズします。
ConnMaxIdleTimeこの閾値よりかなり下に設定し、アイドル期間後の最初のクエリでdriver: bad connectionエラーを避けてください。 非トランザクションコールの場合、 database/sql 新しい接続で自動的に再試行されます。 トランザクションコールの場合、コードがエラーを検出し、トランザクション全体を再試行しなければなりません。
フェイルオーバー後の再接続
外部取引では、 database/sql が接続不良で開始された通話を、ドライバーが接続を使用不能とマークした場合に、透過的に再試行できます。 この動作は、スロットリングやフェイルオーバー、その他の再試行可能なSQLエラーに対する完全な一時故障再試行ポリシーではありません。 データベース呼び出しをリトライ関数でラップして、これらのシナリオを処理します:
var count int
err := RetryFunc(ctx, DefaultRetryConfig, func(ctx context.Context) error {
return db.QueryRowContext(ctx, "SELECT COUNT(*) FROM HumanResources.Employee").Scan(&count)
})
Azure SQL Managed Instance
Azure SQL Managed InstanceはオンプレミスのSQL Serverと同じドライバー機能をサポートしていますが、いくつかの違いがあります。
| 特徴 | Azure SQL Database | Azure SQL Managed Instance |
|---|---|---|
| SQL Server エージェント(SQL サーバー エージェント) | 該当なし | Available |
| 複数データベースにまたがるクエリ | 該当なし | Available |
| 連結サーバー | 該当なし | Available |
| 名前付きパイプ | 該当なし | 利用不可(TCPのみ) |
| 共有メモリ | 該当なし | 利用不可(TCPのみ) |
| Windows 認証 (SSPI) | 該当なし | マネージドVNet内で利用可能です |
Managed Instanceに接続:
sqlserver://<user>:<password>@<instance>.database.windows.net?database=<database>&encrypt=true&TrustServerCertificate=false
Microsoft Fabric の SQL データベース
Important
FabricのSQLデータベースにはMicrosoft Entra ID認証が必要です。 SQL Server認証はサポートされていません。
本番ワークロードでは、新しい接続での認証チェーンプローブのオーバーヘッドを避けるため、fedauthではなく明示的なActiveDirectoryDefaultモードを好む。
FabricのSQLデータベースは、Microsoft Entra ID認証付きのgo-mssqldbドライバーをサポートしています:
db, err := sql.Open("azuresql",
"sqlserver://<server>.database.fabric.microsoft.com?database=<database>&fedauth=ActiveDirectoryDefault&encrypt=true&TrustServerCertificate=false")
if err != nil {
panic(err)
}
Azure SQL のパフォーマンス向上のヒント
| Tip | 詳細情報 |
|---|---|
| 接続プーリングを使用する | Azure SQLは、開いている各接続をティア制限にカウントします。
MaxOpenConnsを縛りつけておけ。 |
encrypt=strict を有効にする |
最も強力なセキュリティを確保するには、TDS 8.0暗号化: encrypt=strictを使用します。 Azure SQL Databaseは厳格モードをサポートしています。 |
ApplicationIntent=ReadOnly を使用する |
読み取り負荷の高いクエリを読み取りレプリカにルーティングする: ApplicationIntent=ReadOnly。 プレミアム、ビジネスクリティカル、ハイパースケールの各ティアで利用可能です。 |
| DTU/vCoreの使用状況を監視してください | CPUやIO、ワーカーの使用率が高い場合は、ティアが小規模である可能性があります。 Azure Monitorを使ってリソース利用率を追跡してください。 |
| 取引は短くまとめましょう | Azure SQLは、リソースの閾値を超えるトランザクションがあるセッションを終了します(エラー40549)。 |
| リージョン エンドポイントの使用 | アプリケーションをデータベースと同じAzureリージョンに配置して遅延を最小限にしましょう。 |
Azure SQL のトラブルシューティング チェックリスト
| 症状: | 考えられる原因 | ソリューション |
|---|---|---|
Cannot open server |
ファイアウォールルールが欠落しています | IPアドレスを追加するか、Azureサービスへのアクセスを有効にしてください。 |
Login failed |
認証情報の誤りやデータベースユーザーの欠落 | ログインが存在し、データベースにアクセスできるか確認してください。 |
| 接続は断続的にタイムアウトします | サーバーの再構成またはフェイルオーバー | リトライロジックと接続回転を実装してください。 |
Resource limit reached |
同時接続が多すぎる |
MaxOpenConnsを下げ、すぐに関係を閉じましょう。 |
The service is currently busy |
Azure SQL のスロットリング | 指数バックオフを使用して再試行します。 スケールアップを検討してください。 |
| 正常に動作していた後でクエリが遅くなる | DTU/vCoreの枯渇 | Azure Monitor metricsをチェックしてください。 クエリを拡大または最適化しましょう。 |