Azure Database for PostgreSQL Flexible Server が “starting” のまま数日間進まず、ポータルの Stop がグレーアウト、CLI でも ServerBusyWithOtherOperation(環境によっては SeverBusyWithOtherOperation と表示)で弾かれる――この状況は運用者にとって極めて厄介です。本記事では、再現しやすい原因の考え方から、現場で使える切り分け手順、サポートへの伝え方、再発防止の運用設計までを一気通貫で解説します。
この現象の全体像と前提
対象は Azure Database for PostgreSQL Flexible Server(例:B1ms/1 vCore/2 GiB RAM/32 GiB)。症状は state=Starting が長時間継続し、ポータルや CLI による停止・再起動が受け付けられないものです。バックエンドでは ARM の非同期長時間操作(LRO: Long-Running Operation)が並列・連鎖しており、内部ロックや保留ジョブが解放されないと「次の操作」が進みません。このためフロント(Portal/CLI)からの命令が 別の操作でビジー
として拒否されます。
まず押さえる結論(エグゼクティブサマリー)
- 最短ルートは Microsoft サポートへのエスカレーション:内部ジョブをキャンセルして強制停止(Stopped)へ遷移させると復旧するケースが多い。
- 自己解決は 状態の客観確認 → 再試行(restart) → 諦め時の見極め が重要。
ServerBusyWithOtherOperationが続くなら粘らずチケット。 - 再発防止は 並列管理操作の抑止、メンテナンスウィンドウの活用、監視による異常検知、HA/ゾーン冗長 の4点で堅牢化。
症状の典型パターンと判断基準
以下のどれかが当てはまると「内部ジョブがハングしている可能性が高い」と判断できます。
| 観測ポイント | 典型的な兆候 | 判断の目安 |
|---|---|---|
| サーバー状態(state) | Starting のまま遷移しない | 30分以上継続で異常疑い。2〜3時間超は高確度。 |
| Portal の操作ボタン | Stop がグレーアウト | 内部操作が優先され、ユーザー操作がブロック。 |
| CLI の戻り値 | ServerBusyWithOtherOperation(または SeverBusyWithOtherOperation) | 内部長時間操作が継続。自力復旧の難度が高い。 |
| アクティビティログ | Start/Update/Restart が連続・保留 | 重複オペレーションや衝突の痕跡。 |
最短の解決策:サポートによる内部ジョブ解除と強制停止
もっとも早い復旧は、Microsoft サポートで内部保留ジョブをキャンセルし、サーバーを一旦 Stopped へ遷移させてもらう方法です。これによりロックが解放され、改めて Start して正常な Running 状態へ戻せます。同様の症状(Starting/Stopping/Updating が長時間継続、CLI が BusyWithOtherOperation を返す)は、Portal/CLI からの対処では限界があるため、チケットが最短ルートです。
サポートに伝えるべき最低限の情報
| 項目 | 内容 | 取得コマンド例 |
|---|---|---|
| リソース識別子 | サーバー名、リソースID、サブスクリプションID、リージョン | az postgres flexible-server show --resource-group <RG> --name <NAME> |
| 現在の状態 | state と継続時間(開始時刻) | --query で state を抽出、アクティビティログで時刻確認 |
| 失敗した操作 | コマンド、エラーメッセージ原文、実行時刻 | az postgres flexible-server restart ... の出力保存 |
| 直前の変更履歴 | スケール、パラメータ変更、メジャー/マイナー更新 | az monitor activity-log list で該当イベント列挙 |
依頼文では「内部操作がハングしており停止・再起動不可。内部ジョブの解除と強制停止(Stopped)への遷移を希望」と明記すると意思疎通が早くなります。
自己解決を試す場合の現場手順
1) 状態を客観的に確認
az postgres flexible-server show \
--resource-group <RG名> --name <サーバー名>
state が Starting のまま 30 分以上進まなければ異常のシグナルです。短時間の「遷移中」と長時間の「ハング」を切り分けるため、必ず時刻と回数を記録しましょう。
2) 再試行できる操作(失敗で長引かせない)
# 再起動(最初に試す)
az postgres flexible-server restart \
--resource-group <RG名> --name <サーバー名> --subscription <SID>
# 停止(ボタンが無効な場合は CLI で試行)
az postgres flexible-server stop
--resource-group --name <サーバー名>
いずれも ServerBusyWithOtherOperation が連続するなら、徒労を避けてチケット提出へ舵を切ります。むやみに叩くと内部キューが増え、かえって復旧を遅らせる恐れがあります。
3) サポートチケットを出すタイミング
Startingが 30 分以上継続、再起動/停止がいずれも Busy。- アクティビティログに Start/Update が連続し、古いものが完了しないまま。
- 業務影響が出ており、フェイルオーバー先がない。
4) 収集しておくとよいログ・メタデータ
# 直近 24 時間のアクティビティログ(操作名と状態)
az monitor activity-log list \
--resource-id <リソースID> --offset 24h \
--query "[].{time:eventTimestamp,op:operationName.value,status:status.value}" \
-o table
# サーバーの概要(SKU/ゾーン/バージョン等)
az postgres flexible-server show
--resource-group --name <サーバー名> -o json
なぜ「Starting のまま」になるのか:技術的背景
Flexible Server の管理操作(Start/Stop/Update/Restart/Scale など)は、Azure Resource Manager (ARM) 経由の非同期 API とバックエンドのコントロールプレーンで処理されます。以下の条件が重なると内部ロックが解放されず、外部操作が BusyWithOtherOperation で拒否されやすくなります。
- 複数の管理操作の同時実行:たとえば「SKU サイズ変更 → 直後に停止」のような連続発行。
- 自動更新や保守の重複:メンテナンスウィンドウ中のパッチ適用と手動操作の衝突。
- 長時間の更新処理:ストレージ拡張や多数のパラメータ変更が絡むアップデート。
- 障害復旧中の再操作:バックエンドの再試行とユーザー操作が競合。
このような内部保留ジョブは、ユーザー側からキャンセルできない性質のものがあり、結果として Portal/CLI の Stop ですら受け付けられなくなります。だからこそ、サポートによる内部ジョブの解除が決定打になります。
状態コードとアクション早見表
| state | 意味 | 通常所要 | 運用アクション |
|---|---|---|---|
| Running | 正常稼働 | — | 監視継続 |
| Starting | 起動中(内部処理含む) | 数分〜十数分 | 30分超で異常疑い。再起動→ダメならチケット。 |
| Stopping | 停止処理中 | 数分 | 30分超は内部ハング疑い。チケット。 |
| Updating | 構成変更反映中 | 内容に依存 | 重複操作を避ける。長時間は要調査。 |
| Stopped | 停止済み(課金停止) | — | 必要に応じ起動 |
エラーメッセージの読み方と対応
| エラー(例) | 状況 | 対応要領 |
|---|---|---|
ServerBusyWithOtherOperation(一部環境で SeverBusyWithOtherOperation) | 内部長時間操作が進行中 | 再試行は限定的に。継続するならサポートで内部ジョブ解除。 |
AnotherOperationInProgress | 同一リソースへの並列指示 | 操作を直列化し、窓口を一つに絞る。 |
OperationTimedOut | バックエンドのタイムアウト | 内部状態が不整合化の恐れ。チケット推奨。 |
運用現場のベストプラクティス(予防策)
並列管理操作を防ぐ
- 運用手順書で Start/Stop/Update/Scale を直列化。1 操作あたり監視で完了を確認してから次へ。
- CI/CD や IaC(Bicep/Terraform)でも dependsOn を明示し、同一サーバーへの同時変更を禁止。
メンテナンスウィンドウの設定と可視化
- 業務時間外に固定し、運用操作は窓外で実施。
- 変更カレンダーをチーム全員が参照できる場所に集約。
Azure Monitor とアクティビティログで兆候を検出
以下は「起動/更新の連続」を検知する例です。
# 直近 6 時間で Start/Update/Restart を抽出
az monitor activity-log list \
--resource-id <リソースID> --offset 6h \
--query "[?contains(operationName.value, 'flexibleServers') && (contains(operationName.value,'start') || contains(operationName.value,'update') || contains(operationName.value,'restart'))].{time:eventTimestamp,op:operationName.value,status:status.value}" \
-o table
HA/ゾーン冗長の活用
- 重要系は ゾーン冗長 または HA レプリカ を構成し、片系障害・ハング時に 即時フェイルオーバーできる導線を用意。
- フェイルオーバー手順は runbook 化し、訓練で確認。
小規模 SKU での運用注意
- B1ms のような最小構成はコスト効率が良い一方、起動時に処理が重なると遷移に時間がかかる場合があります。定期業務が重なる時間帯を避けるなど、負荷分散を意識。
「Starting ハング」を自動検知・エスカレーションする仕組み
障害を 人間の気付き に頼らず、検知・一次対応を自動化すると回復が早まります。
監視 → 通知 → 判断の流れ
- 監視:定期ジョブが
stateをポーリング(例:5分間隔)。 - 閾値:
Startingが 30 分継続で Warning、60 分で Critical。 - 自動一次対応:
restartを 1 回だけ試行(再入禁止)。 - 失敗時:オンコールへ通知+サポートチケットの雛形を自動生成。
サンプル:簡易スクリプト(擬似例・概念提示)
#!/usr/bin/env bash
set -euo pipefail
RG=""
NAME="<サーバー名>"
STATE=$(az postgres flexible-server show -g "$RG" -n "$NAME" --query state -o tsv)
if [[ "$STATE" == "Starting" ]]; then
# 直近の継続時間は外部のストア等で管理する想定
echo "Server in Starting. Attempting single restart..."
if ! az postgres flexible-server restart -g "$RG" -n "$NAME" ; then
echo "Restart failed (busy). Escalate to support."
# ここで通知・チケット雛形出力
fi
fi
ポイントは「再起動は 1 回だけ」「失敗時は 即エスカレーション」。むやみに発行しないことが安定運用に直結します。
サポートへの提出テンプレート(コピペ可)
件名: Azure Database for PostgreSQL Flexible Server が Starting から遷移せず操作不可
現象:
* 対象: サーバー名 (/subscriptions//resourceGroups//providers/Microsoft.DBforPostgreSQL/flexibleServers/)
* 状態: state=Starting が <継続時間> 続く
* Portal: Stop ボタンがグレーアウト
* CLI: restart/stop が ServerBusyWithOtherOperation で失敗
* 影響: 業務影響 <具体的に>
直前の操作・変更:
* <例: SKU 変更、パラメータ更新、OS/エンジン更新など>
要望:
* 内部で保留されているジョブのキャンセル
* サーバーの強制停止(Stopped)への遷移
* 必要に応じたバックエンド側の再整合処理
よくある引き金と回避策の対照表
| 引き金 | 説明 | 回避策 |
|---|---|---|
| 連続した管理操作 | Update → 即 Stop/Start など | 操作間に完了確認(通知/監視)を挟む。自動化は直列化。 |
| メンテナンスウィンドウ中の手動操作 | 自動更新と衝突 | ウィンドウ外で実施。更新カレンダーを共有。 |
| 大規模スケールとパラメータ変更の同時適用 | 内部処理が重く長引く | 変更を小分けにし、影響を局所化。 |
| 障害復旧中の追加操作 | バックエンドの再試行と競合 | 復旧フローが完了するまで新規操作を禁止。 |
課金とビジネス影響の観点
- Stopped でない限り、コンピュート課金は基本的に継続します(構成に依存)。長時間の Starting は、止めたいのに止められず課金が続くという観点でも深刻です。
- 運用 SLA を満たすには、代替系(HA/レプリカ)とフェイルオーバープロセスの整備が実務的に不可欠です。
現場で役立つチェックリスト
| 確認項目 | 目的 | コマンド例 | 合格基準 |
|---|---|---|---|
| state の継続時間 | ハング判定 | az postgres flexible-server show | 30 分以内なら様子見、超過で対応開始 |
| 重複操作の有無 | 衝突検知 | az monitor activity-log list | Start/Update/Restart が重複していない |
| 再起動 1 回の結果 | 自己解決の可能性評価 | az postgres flexible-server restart | 成功しないならチケットへ |
| HA/DR の切替可否 | 業務継続 | 手順書・Runbook | RTO/RPO 目標内で切替可能 |
PowerShell での代替コマンド(併用時の注意)
運用チームに PowerShell 文化がある場合は、Az モジュールでも観測できます(環境に応じてコマンドレット名は異なる場合があります)。CLI と同時に叩かず、窓口を一本化しましょう。
# 概念例(実環境のモジュールに合わせて読み替え)
Get-AzPostgreSqlFlexibleServer -ResourceGroupName <RG> -Name <NAME> | Select-Object Name, State, Location, SkuName
Restart-AzPostgreSqlFlexibleServer -ResourceGroupName -Name
Stop-AzPostgreSqlFlexibleServer -ResourceGroupName -Name
Bicep/Terraform 運用時の注意(並行デプロイの落とし穴)
- 同一サーバーを複数スタックから変更しない。責務分離し、Single Writer 原則を採用。
- 依存関係(dependsOn)で順序を固定。lifecycle 設定で無駄な再作成を抑制。
- Plan/Preview 結果に管理操作(Start/Stop/Update)が紛れていないかレビュー。
再発防止:設計面での具体策
ブルー/グリーン構成(段階的切替)
更新時に既存系(Blue)をいじらず、新系(Green)を育ててからトラフィックを切り替えます。切替失敗時は Blue にロールバック。管理操作の衝突を根本的に避けられます。
読み取りレプリカの活用
読み取り系を分離し、プライマリへの管理操作の影響を小さくします。プライマリがハングしてもレプリカで暫定対応できる場合があります。
フェイルオーバー手順の自動化
名前解決(CNAME/Private DNS)を切替ポイントにし、DB 接続文字列の上位で抽象化。切替に伴うアプリ再起動やコネクションドレインもスクリプト化します。
トラブル時に「やってはいけない」こと
- 成功しない操作を短時間に繰り返す:内部キューが増え悪化します。
- 本番で安易にサーバー再作成:データ喪失のリスク。バックアップ/スナップショットの確認なしに実施しない。
- 障害情報の非共有:当事者以外が並行操作して衝突する温床になります。
ケーススタディ:強制停止→再起動で復旧した例
ある環境で、スケール変更(vCore 増)直後に停止指示を出した結果、Starting/Updating が交互に並び、以降の操作がすべて Busy。サポートで内部保留ジョブをキャンセルし、Stopped へ遷移。その後の Start で Running に回復し、接続も正常化しました。以降は運用規約を見直し、各操作の完了確認を必須化、CI からの変更も直列制御に改めて再発は止まりました。
付録:JSON 出力の読み方(抜粋)
{
"name": "<server-name>",
"location": "<region>",
"state": "Starting",
"sku": { "name": "Standard_B1ms", "tier": "Burstable" },
"version": "14",
"highAvailability": { "mode": "Disabled" },
"storage": { "storageSizeGB": 32 },
"backup": { "backupRetentionDays": 7 }
}
state:最重要フィールド。ここがStarting固定か。sku.name:SKU が変更されていないか。highAvailability.mode:HA の有無。storage.storageSizeGB:ストレージ変更の痕跡。
まとめ:現場で迷わない判断基準
- 30 分ルール:
Startingが 30 分以上なら異常疑い。自己再起動 1 回まで。 - Busy 連発=チケット:
ServerBusyWithOtherOperationが続くならサポートへ。 - 並列禁止:Portal/CLI/IaC/自動化を含め、単一路の操作窓口に。
- 設計で予防:メンテナンスウィンドウ、監視、HA/DR、ブルーグリーン。
要点:“starting” から進まないのは内部ジョブのハングが主因。CLI の Busy は自力復旧ほぼ不可。サポートに依頼し「強制停止 → 再起動」で正常化。今後は並列操作を避け、監視とメンテ設定で未然防止。
実務でそのまま使えるコマンド集(保存版)
# 状態確認
az postgres flexible-server show \
--resource-group <RG名> --name <サーバー名>
# 再起動(1 回だけ試す)
az postgres flexible-server restart
--resource-group --name <サーバー名> --subscription
# 停止(ポータル不可時の代替)
az postgres flexible-server stop
--resource-group --name <サーバー名>
# アクティビティログの要約(直近 12h)
az monitor activity-log list
--resource-id <リソースID> --offset 12h
--query "[].{time: eventTimestamp, op: operationName.value, status: status.value}"
-o table
最後に:運用設計を“人に依存させない”
柔軟なマネージドサービスほど、人のタイミングが衝突要因になります。操作の直列化・自動化と、HA/DR の事前準備は、障害の回避と軽微化の両輪です。本記事の手順と設計ヒントを組み合わせれば、同様のトラブルに遭遇しても、迷いなく最短で復旧に向かえます。

コメント