Switzerland North の Azure SQL Managed Instance(MI)で、2025年8月16日以降テスト環境の計画メンテナンスがほぼ毎日「Cancelled」になる一方、本番では通常どおり完了している——このギャップは運用判断を迷わせます。本記事は実運用で遭遇した事例を基に、原因仮説、確認・対処手順、再発防止策、監視設計までを一気通貫で解説します。
事象の背景と観察されたパターン
以下は発生状況の要点です。
- 対象:Azure SQL Managed Instance(リージョン:Switzerland North)
- テスト用インスタンスのみ影響:2025年8月16日以降、ポータルの Operations > Maintenance に「Cancelled」が異常に多発
- 本番インスタンス:同時期のジョブは通常どおり「Complete」
- 運用歴:約3年以上。これほどの連続キャンセルは初
- Microsoft へ調査依頼ののち、直近の 2025‑09‑13(ジョブ ID: WNB7‑VR8)と 2025‑09‑14(ジョブ ID: XSHG‑T_0)は「Complete」で収束傾向
このような「テストのみ再現・本番は正常」という現象は、メンテナンスポリシー適用の違い、実行タイミングの競合、依存サービスの状態変化、ワークロード特性などの複合要因で起きます。以下で深掘りします。
なぜ「Cancelled」が続くのか(主な原因と見分け方)
「Cancelled」は単なる単発の中止ではなく、安全のための延期(Postpone/Defer)やロールバックの結果であることが多く、根本要因は次のいずれか、もしくは組み合わせです。
メンテナンスポリシーによる安全な延期(プラットフォーム判断)
MI は基盤の健全性(Compute/Storage/ネットワーク)や、同一物理ホスト上の他ワークロード、マルチテナント環境の負荷、内在する自動フェールオーバーのリスクなどを評価し、安全でないと判断すればメンテナンスを自動的に延期します。延期が繰り返されると、履歴上は「Cancelled」が連日続いて見えます。
パッチ適用失敗 → ロールバック → 別ウィンドウに再スケジュール
特定ビルドのパッチが当該インスタンスまたは基盤で失敗した場合、自動ロールバック後に同じ更新が別のメンテナンスウィンドウに自動再スケジュールされます。失敗が続く、もしくはウィンドウが狭く重いワークロードと競合すると、結果として連続キャンセルに見えます。
リング配信(段階展開)による一時停止
MI の更新は一般に段階展開(Safe Deployment)で行われます。先行リングの一部でリスクシグナルが上がると、特定のリージョンや一部クラスターで展開保留がかかり、個々のインスタンスでは「Cancelled」が増えることがあります。
ワークロード由来の阻害(長時間トランザクション・ロック・メンテナンスウィンドウ設定の不整合)
- 長時間トランザクションや常時高負荷(バッチ/バックアップ/統計更新/インデックス再構築/夜間ETL)とメンテナンスウィンドウが衝突。
- SQL Agent ジョブや Elastic ジョブ、外部接続(Data Sync/Linked Server/PolyBase 代替ワークロード等)がメンテナンス開始トリガーと競合。
- ウィンドウが短すぎる/分散しすぎるため完了までに時間枠が足りない。
インスタンス構成・サイズ差による挙動差
本番とテストで vCore/ストレージ/バックアップ保持/可用性構成(可用性グループ/フェールオーバー グループ)の違いがあると、更新に必要な停止・再起動時間やデータ移行量が変わり、キャンセル耐性に差が出ます。
「Cancelled」の読み方(早見表)
| 表示 | 典型的な意味 | 直近の取るべき行動 |
|---|---|---|
| Cancelled(単発) | 安全性/競合を検知し延期 | 履歴・Activity Log を確認し、次回窓で完了するか監視 |
| Cancelled(連日・連続) | 繰り返しの競合 or ロールバック→再スケジュール | ワークロード/ウィンドウ/失敗コードを精査。必要なら窓の再設計とサポート連携 |
| Complete | 更新完了 | バージョン上昇/ビルド変更を確認し平常運転へ |
最短ルートでの確認・対応フロー
以下の手順で「何が」「どこで」止まっているかを短時間で切り分けできます。
| 手順 | 内容 | 確認ポイント/備考 |
|---|---|---|
| ① メンテナンス履歴の確認 | Azure ポータル → 対象 MI → Operations → Maintenance | 直近数週間の状態遷移、ジョブ ID、失敗/キャンセル理由、エラーコードを控える |
| ② Service Health / Resource Health | ポータル左ペインの Service Health → Planned Maintenance / Resource Health | リージョン/クラスター単位の既知事象や保留アナウンスを確認 |
| ③ バージョン確認 | SELECT @@VERSION; / SERVERPROPERTY 系でビルド比較 | 予定ビルドに上がっていれば解消に向かっているサイン |
| ④ メンテナンス時間帯の見直し | MI の Availability(可用性)配下の Maintenance window を調整 | 競合ワークロード(夜間ETL/バックアップ/統計更新/再構築)をずらす |
| ⑤ Azure サポートへのエスカレーション | 状況ログ(ジョブ ID/時刻/エラー/リージョン/リソース ID)を添付 | プラットフォーム側の詳細ログで根因調査を依頼 |
バージョン・状態のクイックチェック(T‑SQL)
-- サーバーバージョン(ビルド)の確認
SELECT
SERVERPROPERTY('ProductVersion') AS ProductVersion,
SERVERPROPERTY('ProductLevel') AS ProductLevel,
SERVERPROPERTY('Edition') AS Edition,
@@VERSION AS FullVersionString;
-- 長時間トランザクションの有無(メンテと衝突しやすい)
SELECT
at.transaction_id,
at.name,
at.transaction_begin_time,
DATEDIFF(minute, at.transaction_begin_time, SYSDATETIME()) AS minutes_open,
es.session_id,
es.program_name,
es.login_name
FROM sys.dm_tran_active_transactions at
LEFT JOIN sys.dm_tran_session_transactions st ON at.transaction_id = st.transaction_id
LEFT JOIN sys.dm_exec_sessions es ON st.session_id = es.session_id
WHERE at.transaction_begin_time IS NOT NULL
ORDER BY minutes_open DESC;
-- メンテナンスウィンドウ帯に走っているSQL Agent ジョブの把握
SELECT
j.name AS job_name,
h.run_date, h.run_time,
h.run_duration,
CASE h.run_status WHEN 0 THEN 'Failed' WHEN 1 THEN 'Succeeded'
WHEN 2 THEN 'Retry' WHEN 3 THEN 'Canceled' ELSE 'Unknown' END AS status
FROM msdb.dbo.sysjobhistory h
JOIN msdb.dbo.sysjobs j ON h.job_id = j.job_id
WHERE h.step_id = 0 -- ジョブ全体の実行履歴
AND CONVERT(datetime, CONVERT(varchar(8), h.run_date), 112) >= '2025-08-01'
ORDER BY h.run_date DESC, h.run_time DESC;
プラットフォーム側イベントの把握(Activity Log)
ポータルの Activity log で対象 MI の時系列イベントを確認します。CLI/PowerShell でも取得可能です。
# Azure CLI(対象期間のアクティビティログを抽出)
az monitor activity-log list \
--resource-id "/subscriptions/<SUBID>/resourceGroups/<RG>/providers/Microsoft.Sql/managedInstances/<MI_NAME>" \
--start-time "2025-08-15T00:00:00Z" \
--end-time "2025-09-30T23:59:59Z" \
--offset 0
# PowerShell
Get-AzActivityLog ` -ResourceId "/subscriptions/<SUBID>/resourceGroups/<RG>/providers/Microsoft.Sql/managedInstances/<MI_NAME>"`
-StartTime (Get-Date "2025-08-15") `
-EndTime (Get-Date "2025-09-30")
ここで、Planned Maintenance、Update applied、Cancel/Defer といったエントリの関連性を時系列で確認します。キャンセル連発時は、開始直前に長時間実行ジョブや接続スパイクが重なっていないかも併せて見ます。
「テストだけ連続キャンセル」の切り分けポイント
| 観点 | 本番 | テスト | 影響/コメント |
|---|---|---|---|
| メンテナンスウィンドウ | 広め(5時間以上) | 狭い/分散 | 時間切れで延期→キャンセルが増える |
| ジョブ密度 | 夜間は抑制/調停済み | テストでも夜間ETL/負荷試験を実施 | 競合確率が上がる(特に統計/再構築/バックアップ) |
| インスタンス規模 | vCore大/IO早い | vCore小/IO遅い | 再起動/フェールオーバー/キャッチアップに時間がかかる |
| フェールオーバー構成 | FG構成/DR先あり | 単体運用またはDR未整備 | 安全側判定で延期されやすい |
| 依存サービスの差 | 共通/安定 | 別クラスター/別物理ホスト | 基盤側事象の影響がテストのみに偏在し得る |
今回の経過と結果(時系列)
- 2025‑08‑16:テスト MI で「Cancelled」開始。以降ほぼ連日。
- 本番 MI:同期間のジョブは「Complete」継続、業務影響なし。
- ログ収集・Activity Log/Service Health/バージョン差分を整理し Microsoft へ調査依頼。
- 2025‑09‑13(WNB7‑VR8)・2025‑09‑14(XSHG‑T_0):テスト環境でも「Complete」を確認。連続キャンセルは収束傾向。
このことから、一時的なプラットフォーム側の保留/再スケジュール要因に加え、テスト環境特有の競合(ウィンドウ/ジョブ)が重なっていた可能性が高いと推測できます。
実践的な対処策(すぐできるものから)
メンテナンスウィンドウの再設計
- テスト環境でも連続した十分な時間幅(例:3〜5時間)を確保。
- 夜間バッチ/ETL/統計更新/インデックス再構築/バックアップの同時実行を避ける(時間帯のずらし・週次の偏りを解消)。
- ウィンドウ直前・直後30分はジョブを抑制し、長時間トランザクションの発生を禁止する運用ルールを徹底。
ワークロードの「メンテナンス・フレンドリー」化
- 長時間トランザクションを分割(バッチサイズ調整・コミット間隔短縮)。
- 並列度上限(MAXDOP)やリソースクラス/リソースガバナー(MI の場合はワークロード管理)でピークを平準化。
- 統計更新は
WITH RESAMPLE, INCREMENTALの活用やターゲット列の絞り込みで時間短縮。
監視・検知の強化(通知の二段構え)
- Service Health アラート:リージョンの計画メンテナンス/保留を通知。
- Activity Log アラート:対象 MI の Update/Cancel/Defer イベントでトリガー。
- SQL Agent ジョブ監視:ウィンドウ帯のジョブ失敗や長時間実行を検知。
障害時のビジネス影響を抑える設計
- Auto-failover グループ(MI 間)をテストでも用意し、切替検証を定期実施。
- バックアップ/ポイントインタイム リストア(PITR)のリハーサルを四半期ごとに行い、RTO/RPO を実測管理。
サポート依頼時に揃えるべき情報(テンプレート)
・対象サブスクリプションID / リソースグループ / MI 名 / リソースID
・リージョン:Switzerland North
・発生日:2025-08-16 以降(時刻はUTC/ローカル併記)
・症状:Maintenance が連日 Cancelled(本番は Complete)
・直近のジョブID:例)WNB7‑VR8(2025‑09‑13)、XSHG‑T_0(2025‑09‑14)
・Activity Log 抜粋(イベント名/サマリ/CorrelationId)
・SELECT @@VERSION の結果(前後比較)
・メンテナンスウィンドウ設定(曜日/時間/幅)
・ウィンドウ帯のジョブ一覧(SQL Agent/外部ETL/バックアップ/統計/再構築)
よくある質問(FAQ)
Q. 「Cancelled」は危険な状態ですか?
A. 危険というより安全側の延期と捉えるのが妥当です。ただし連日続く場合は、更新が適用されず脆弱性修正や性能改善が遅れます。ウィンドウ/ワークロード/基盤状況を確認し、必要に応じてサポートに調査を依頼してください。
Q. メンテナンスを強制実行できますか?
A. MI の基盤更新はプラットフォーム管理であり、ユーザーが強制的に「今すぐ適用」する操作は基本的にありません。できるのは衝突要因を減らす運用調整(ウィンドウ再設計・ジョブ抑制)です。
Q. 本番は正常なのにテストだけ Cancelled です。なぜ?
A. リング差、物理ホスト差、インスタンス規模差、ジョブ競合、メンテナンスウィンドウの違いが重なると、テスト側のみ延期が起きやすくなります。上記の切り分け表を参照し、構成差を縮めると収束しやすくなります。
Q. 「Complete」に戻ったら何を確認すべき?
A. ビルド上昇(SERVERPROPERTY('ProductVersion'))とアプリケーション疎通、性能カウンタ、ジョブ結果。加えて、キャンセルが続いていた期間のアラートやエラーの後片付け(抑制解除・スケジュール戻し)を行います。
運用ナレッジ:メンテナンスと衝突しやすいタスクの優先度付け
| タスク | 衝突リスク | 推奨アクション |
|---|---|---|
| 大規模インデックス再構築 | 高 | メンテ窓外へ移動。REBUILD WITH (ONLINE=ON, MAXDOP=1〜2) 等で穏やかに |
| 統計更新(全テーブル一括) | 中〜高 | 対象列を絞る/インクリメンタル化/メンテ窓外へ |
| 長時間ETL/バルクロード | 高 | バッチ分割とコミット頻度の向上、窓外へ |
| フルバックアップ | 中 | 差分/ログの組み合わせで窓内の負荷を下げる |
| 負荷試験 | 高 | テストでもメンテ窓とは絶対に重ねない |
監視・アラート設計(すぐ効く実装の雛形)
- Activity Log アラート:「Operation name contains ‘Update’ or ‘Maintenance’」「Status=Failed/Canceled」で通知。
- Service Health アラート:リージョンの計画メンテナンス/既知事象の発生・回復で通知。
- ログ連携:MI の診断ログを Log Analytics へ送信し、KQL でメンテ窓帯のジョブ/クエリの分布を可視化。
// KQL 例(Activity LogをLog Analyticsに送っている場合)
AzureActivity
| where ResourceProviderValue == "MICROSOFT.SQL"
| where Resource == "<MI_NAME>"
| where OperationNameValue contains "Maintenance" or OperationNameValue contains "Update"
| project TimeGenerated, OperationNameValue, ActivityStatusValue, CorrelationId, ResultDescription
| order by TimeGenerated desc
再発防止の実務チェックリスト
- メンテナンスウィンドウは連続3時間以上確保し、前後30分はジョブ禁止。
- テストでも本番とできるだけ同じ規模・同じスケジュールに寄せる。
- 長時間トランザクションを監視し、一定時間(例:60分超)でアラート。
- Service Health/Activity Log の通知をメール・Teams へ二重配信。
- 四半期ごとの DR リハーサル(Auto‑failover グループの強制切替を含む)。
- 重大アプライ遅延(例:連続7日以上の Cancelled)で自動エスカレーション。
まとめ
Azure SQL MI の「Cancelled」連発は、単なる失敗ではなく安全側の制御と再スケジュールの結果であることが多く、ウィンドウ設計・ワークロード調整・プラットフォーム状況の把握で高確率に収束します。本件でも、Microsoft 連携と運用調整の併走により、2025‑09‑13/14 のジョブで「Complete」を確認し正常化しました。今後は、事前通知とアラートの二段構え、テスト/本番のスケジュール整合、長時間トランザクションの抑制という三本柱を標準化することで、再発の芽を早期に摘み取れます。
付録:運用ドキュメント雛形(社内共有用)
■ 件名
[MI/Switzerland North] 計画メンテナンス Cancelled 連発の経緯と対処
■ 影響
テスト環境のみ。プロダクション影響なし。
■ 期間
2025-08-16 〜 2025-09-14(以降収束)
■ 原因(推定)
・プラットフォーム側保留+ウィンドウ/ジョブの競合
・テスト固有の長時間処理
■ 対処
・メンテ窓の連続確保(3〜5h)と前後30分のジョブ抑止
・長時間Tx/Agentジョブの整理
・Activity Log/Service Health アラートの導入
・Microsoft へログ提供のうえ調査依頼
■ 再発防止
・テスト/本番のスケジュール整合
・DR/フェールオーバー検証の定例化
・遅延しきい値で自動エスカレーション
補足:用語の簡易整理
- Maintenance window:プラットフォーム更新の優先適用時間帯。十分な時間幅とジョブ抑止が鍵。
- Cancelled:実施見送り/開始後中止。延期やロールバック再試行を含む広い概念。
- Complete:更新完了。バージョン/ビルドの上昇で確認。
- Service Health:リージョンやサービスの計画メンテナンス・既知の問題を告知するポータル機能。
実装メモ:安全な夜間バッチの設計指針
- メンテナンス窓と重ならない時間に配置(カレンダーを参照し固定化)。
- 処理は多数の小さなコミットへ分割し、即時再実行可能な冪等性を確保。
- 重い DDL/インデックス処理はオンライン化・並列度制御で影響を最小化。
- ジョブ間の依存関係を見直し、長時間化時のサーキットブレーカー(タイムアウト・強制キャンセル)を実装。
今回のポイントを一枚に
| 領域 | やること | 期待効果 |
|---|---|---|
| 観測 | Maintenance/Activity/Service Health の三点見取り図 | キャンセルの性質(延期/失敗)を短時間で特定 |
| 制御 | メンテ窓再設計+ジョブ抑制+Tx短縮 | 競合を減らし適用完了率を上げる |
| 連携 | Microsoft へジョブ ID/ログ/時刻を添えて調査依頼 | 基盤側要因の可視化・早期収束 |
| 継続 | アラート標準化とDR訓練の定例化 | 次回発生時の復旧時間短縮/影響限定 |
結論
「Cancelled」が連日続くと不安になりますが、慌てる必要はありません。重要なのは、証拠を揃えて(履歴・Activity・バージョン)、競合を減らす(ウィンドウ/ワークロード)、関係者で早く共有し、必要に応じて Microsoft と連携する——この三つです。本稿の手順とチェックリストをそのまま適用すれば、原因の切り分けと再発防止を現実的なコストで実現できます。

コメント