概要
Proxmox Backup Server (現:PBS 7.0.0) で Wasabi S3 バックエンドにバックアップ中、プロセスが約3時間フリーズして強制終了される事象が多発した。原因は Linux の TCP keepalive のデフォルト値が長すぎることによる「TCPブラックホール」で、keepalive パラメータを調整することで解決した。
環境
- PBS バージョン: 7.0.0-3-pve(Debian GNU/Linux ベース)
- バックアップ先: Wasabi S3(シンガポールリージョン
ap-southeast-1) - 対象 VM: VM 118(64GB ディスク)
- PVE ノード: pve2
症状
定期バックアップジョブ(毎日 04:15 実行)のログを確認すると、VM 118 のバックアップだけが失敗していた。
INFO: 26% (17.1 GiB of 64.0 GiB) in 2m 9s, read: 249.3 MiB/s, write: 40.0 MiB/s
INFO: 26% (17.1 GiB of 64.0 GiB) in 3h 2m 23s, read: 33.0 KiB/s, write: 31.4 KiB/s
ERROR: backup write data failed: command error: write_data upload error:
pipelined request failed: Unable to acquire lock
"/run/proxmox-backup/locks/wasabi/.chunks/2f97/..." -
Interrupted system call (os error 4)
ポイント:
- 2分9秒時点では 249 MiB/s で正常動作
- その後 約3時間、17.1GiB の地点でほぼ完全に停止(33 KiB/s まで低下)
- エラーは
os error 4=EINTR(システムコール割り込み) - PBS の UI を含むプロセス全体がフリーズしていた
原因
1. dirty-bitmap が created new になっていた
通常の差分バックアップであれば dirty-bitmap status: OK (X GiB dirty) と表示され、変更分だけを転送する。しかし今回は:
INFO: scsi0: dirty-bitmap status: created new
以前の失敗でビットマップが消えており、64GB のフルバックアップが必要な状態になっていた。これにより転送時間が大幅に伸び、問題が顕在化しやすくなっていた。
2. TCP ブラックホール(本質的原因)
Wasabi(シンガポールリージョン)との長時間 S3 アップロード中に以下の連鎖が発生した:
- 途中の NAT やファイアウォールがアイドルタイムアウトで TCP コネクションをサイレントにドロップ
- FIN/RST が届かないため、PBS 側の OS はコネクションが生きていると認識し続ける
- PBS の chunk uploader がデッドなソケットへの write でブロック
- プロセス全体がハング
Linux のデフォルトの TCP keepalive 設定は:
net.ipv4.tcp_keepalive_time = 7200 # 2時間アイドル後にプローブ開始
今回の停止時間(約3時間)は、2時間の keepalive タイムアウト + その後のプローブ時間とほぼ一致する。つまり 2時間もデッドなコネクションに気づけなかったことが根本原因だった。
3. 負のサイクル
バックアップ失敗
→ dirty-bitmap リセット(created new)
→ 次回もフルバックアップ(64GB)
→ 転送時間が長くなりハングしやすい
→ また失敗 → dirty-bitmap リセット ...(無限ループ)
解決策?
Step 1:TCP keepalive をチューニング
PBS ホストで以下を設定する:
cat << 'EOF' > /etc/sysctl.d/99-tcp-keepalive.conf
# アイドル10分後にkeepaliveプローブ開始(デフォルト: 7200秒)
net.ipv4.tcp_keepalive_time = 600
# 30秒間隔で再送
net.ipv4.tcp_keepalive_intvl = 30
# 5回失敗でコネクション切断
net.ipv4.tcp_keepalive_probes = 5
EOF
sysctl -p /etc/sysctl.d/99-tcp-keepalive.conf
これにより、デッドコネクションを最大 600 + 30×5 = 750秒(約12.5分) で検出・切断できるようになる。
変更前後の比較:
| パラメータ | デフォルト | 変更後 |
|---|---|---|
tcp_keepalive_time |
7200秒(2時間) | 600秒(10分) |
tcp_keepalive_intvl |
75秒 | 30秒 |
tcp_keepalive_probes |
9回 | 5回 |
| デッド検出までの最大時間 | 約2時間42分 | 約12.5分 |
Step 2:PBS 側タイムアウト設定の確認(結果:なし)
PBS の S3 エンドポイント設定にアプリケーションレベルのタイムアウトが存在するか確認した:
proxmox-backup-manager s3-endpoint update wasabi --help 2>&1 | grep -i timeout
# → 何も出力されない
PBS 7.x の S3 バックエンドにはタイムアウト設定が実装されていないため、OS の TCP keepalive が唯一の防衛ラインとなる。
Step 3:dirty-bitmap を回復させるため手動バックアップを実行
TCP keepalive 適用後、PVE ノード(pve2)で手動バックアップを実行:
vzdump 118 --mode snapshot --storage wasabi-backup --notes-template '{{guestname}}'
結果:
INFO: scsi0: dirty-bitmap status: OK (7.6 GiB of 64.0 GiB dirty)
INFO: transferred 7.60 GiB in 165 seconds (47.2 MiB/s)
INFO: Finished Backup of VM 118 (00:02:47)
INFO: Backup job finished successfully
| 失敗時 | 解決後 | |
|---|---|---|
| dirty-bitmap | created new(フル64GB) | OK・差分 7.6GB |
| 所要時間 | 3時間フリーズ→強制終了 | 2分47秒 |
| 転送速度 | 33 KiB/s(停止状態) | 47.2 MiB/s(安定) |
dirty-bitmap が正常に確立されたため、次回の定期バックアップからも差分モードで動作する。
補足:なぜ他の VM は問題なかったか
同ノード内の他7台の VM(100/101/105/110/115/116/117)は今回問題がなかった。理由は以下の通り:
- VM 100, 101:停止状態からのバックアップで短時間(15〜101秒)
- VM 105〜117:dirty-bitmap が確立済みで差分が小さく(0.5〜14.4 GiB)、転送時間が短い
VM 118 だけが dirty-bitmap なし+64GBフルという組み合わせで長時間接続が必要になり、TCP タイムアウトに引っかかった。
まとめ
| 項目 | 内容 |
|---|---|
| 現象 | PBS が Wasabi S3 バックアップ中に約3時間フリーズ |
| エラー | EINTR (os error 4) – ロック取得失敗 |
| 根本原因 | Linux TCP keepalive のデフォルト(2時間)が長すぎ、デッドコネクションを検出できなかった |
| 対策 | TCP keepalive を 600秒に短縮(/etc/sysctl.d/99-tcp-keepalive.conf) |
| PBS側対策 | タイムアウト設定は未実装(PBS 7.x) |
| 復旧 | 手動バックアップで dirty-bitmap を再確立 |
Wasabi のような海外リージョン S3 を使う場合、NAT タイムアウトの影響を受けやすい。長時間転送が発生しうるバックアップ用途では、TCP keepalive の調整は必須の設定と言える。
詰まるところ、、、早期検出はできるようになったものの根本原因の解決には至っていない。原因は、比較的タイムアウトしやすい海外リージョンへS3してることとPBSが自動リトライしてくれない点が相乗していることだろうか汗
検証環境: PBS 7.0.0-3-pve / Wasabi S3 ap-southeast-1 / 2026-08
※本記事は当サイト管理人の個人的な備忘録です。情報内容には配慮しておりますが、本記事の参照または付随ソースコード利用後にいかなる損害が発生しても、当サイト及び管理人はいっさいの責任を負いません。
