
2026/08/01 0:17
並列大規模 PostgreSQL バックアップ
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
PlanetScale は、複雑な内部インフラストラクチャのオーケストレーションによって手動のプロセスを代替することで、データベースのバックアップを根本的に変革し、Postgres と MySQL のバックアップ、スケジュール管理、運用、および復旧を顧客にとって容易にすることを目的としています。ステディーステートのシャード化された PostgreSQL においては、システムはライブのプロダクションシステムに影響を与えることなく大規模な並列処理を取り扱うために、孤立した計算ノードを作成します。バックアップのライフサイクルでは、初期データのために
pg_basebackup を使用して新しい Amazon EC2 インスタンスにシードを行い、その結果を Amazon S3 などのオブジェクトストレージに保存します。最終的な一貫性を確保するために、WAL(Write-Ahead Logs)のリプレイを行うハイブリッドなアプローチが採用され、大部分は S3(wal-g でアーカイブされたもの)からストリーミングし、最後の数分間の変更についてはプライマリから直接取得されます。同様に、シャード化された MySQL のバックアップでは VTBackup とバイナリログレプリケーションを可比の並列性を伴って利用します。このアーキテクチャは迅速なデータ安全性と回復力を可能にし、組織がデータベースのリサイズや故障したノードの置換を行ってもサービス中断を招かないようにします。深い自動化によって技術的な複雑さを隠蔽することで、PlanetScale は運用上の透明性を実現し、バックアップ速度は 50 GB/s を超え(8 シャードにわたって約 40,030 GB を転送するのに約 2.8 時間かかりますが、単一ノードでは約 22 時間かかる)、数日間の必要な作業を容易な操作に変え、データの増加に伴ってシームレスに拡張します。本文
PlanetScale: 大規模シャーディングデータベースの「 effortless」バックアップ戦略
PlanetScale は、Postgres と MySQL のバックアップにおける「作成」「スケジューリング」「管理」「復元」の全工程において、ユーザーにとって極めて容易(effortless)な体験を提供することを目標としています。特にシャーディングされたデータベースに対するバックアップは技術的に複雑でありながら、以下の要件を満たす必要があります:
- 12 時間ごとの一貫性確保:活発なデータベース状態を暗号化されたスナップショットに変換
- プロダクションへの影響排除:バックアップ中のデータベース性能や可用性は一切低下させない
- ペタバイト級のスケーラビリティ:転送速度 1 秒あたり 50GB を超え、数時間で大量データを処理
本記事では、複雑な裏側のプロセスを解説し、大規模並列処理を活用したバックアップの実装方法を深掘りします。
バックアップのライフサイクルとアーキテクチャ
シャーディングされた Postgres データベース(例:Neki)は、数百万回のプロダクショントラフィックを処理しつつ、多数の独立したプライマリサーバーが連携して動作します。バックアップは以下のステップで構成されます。
1. 基本戦略:ファイルシステムと WAL の組み合わせ
PlanetScale が採用しているのは、**「ファイルシステム上の完全バックアップ」と「アーカイブ済み Write-Ahead Log (WAL) の再生」**を併用する手法です。
- ステップ A(時刻 T1):ディスク上のデータベース全体へのバックアップ開始
- ステップ B(時刻 T2):バックアップ完了。T1〜T2 間の行変更の可能性あり
- ステップ C(WAL 再生):T1 と T2 の間に発生した WAL 変更を再生し、データの不整合を是正
- ステップ D(保存):最終結果を Amazon S3(他クラウドのオブジェクトストレージと同様)に保存
2. インフラ構成:専用 EC2 インスタンスの立ち上げ
プロダクショントラフィックを受信するサーバーでバックアップを実行すると、IOPS や計算リソースを消費し、システムに負荷がかかります。そのため、以下のアプローチを採用します。
- シャード数に応じたインスタンスセットの動的起動
- AWS や GCP 上で、短時間だけ数十〜数百台の EC2 インスタンスを立ち上げます。
- これらの新しいインスタンスがバックアップ処理の大半を担当します。
- コストは増えますが、プロダクションへの負荷最小化という観点で価値があります。
過去のバックアップデータの再利用
最新の WAL を取得するだけでなく、直前の完全バックアップデータを復元するプロセスが不可欠です。
処理フロー
- データ取得:オブジェクトストレージ(Amazon S3 など)から過去バックアップをストリーミングして読み出し
- 一時転送:読み出したデータを各シャードの新しいインスタンスに書き込む
- 状態復元:8 つのサーバーがそれぞれ 12 時間前の状態(直近バックアップ時点)を正確に保持
なぜこのコストのある転送が必要か?
以下の 2 つの重要な理由から、一時的な計算リソースとデータ転送コストを受け入れています。
- プロダクションプライマリへの影響最小化
- プロダクションサーバーから直接 WAL を取得するだけで済むため、本番システムへの負荷が大幅に減少します。
- プロセスの検証可能性
- 各サイクルで「前回のバックアップ復元」および「WAL 再生」が正常に完了したことを確認できます。
WAL の再生とハイブリッドアプローチ
古いバックアップを現在のデータベース状態に追従させるため、12 時間分の WAL 変更を再生します。ここで直面する課題と解決策です。
単一アプローチの問題点
プライマリから直接 WAL を取得・読み込む方法には以下の欠点があります。
- プロダクションへの影響が大きい
- ハイパフォーマンスなデータベースの場合、12 時間の WAL 再生に数十分〜1 時間以上かかる可能性があります。
- ストレージ容量の制約
- プライマリノードには過去 12 時間の全 WAL が常駐しておらず、S3 へアーカイブされているためです。
PlanetScale の解決策:ハイブリッドアプローチ
wal-g を用いてすべての Postgres データベースで WAL の連続的アーカイブを行っています。しかし、Postgres のセグメント切り替えタイミング(archive_timeout)と S3 アップロードの間にタイムラグがあるため、完全なストリーミングだけでは最新のデータ変更をキャッチできません。
そこで採用するのは以下のハイブリッド方式です:
- 主な処理:S3 から直接 WAL をストリーミングして取得
- 最終ステップ:直近の数分間のデータについては、プライマリから直接ストリーミングを取得(数秒程度で完了)
この方式により、S3 の容量制約を回避しつつ、最新のデータ変更も確実にキャッチできます。
サイクルの完了と暗号化
すべてのノードが時刻
T までのレプリケーションを完了した時点で、以下の操作を行います。
- 時刻 T の凍結(Freeze):WAL レプリケーションを停止し、バックアップ時点の正確な秒数を記録
- 状態の不整合排除:これで完全で不整合のない(smeared data 含まない)バックアップが完成
- 暗号化と保存:バックアップを暗号化して新しい S3 バケットへ送信
- ノードの除籍:バックアップ処理を終えた担当ノードは使命を終え、リソースとして解放されます
初期バックアップについて(Seed)
上記のサイクルは「12 時間前に健全なバックアップが存在する」という定常状態を前提としています。新規作成データベースについては以下の手順が必要です。
初期化手順 (pg_basebackup
)
pg_basebackup- シャード数に応じて EC2 インスタンスを新規に立ち上げる(各シャード 1 つ)
を実行してプライマリからデータをコピーするpg_basebackup- 各インスタンスをプライマリからレプリケートするように構成
- 全てのインスタンスが追いつくまで WAL を再生
- 時刻 T でレプリケーションを停止し、バックアップを作成
を使用してフォーマット・暗号化し、S3 にアップロードwal-g
なぜ直接アップロードしないのか?
- 一貫性の維持:初期化用としてのみ
を使い、本格的な永続的バックアップは常にpg_basebackup
で作成します。これにより、バックアップ形式と復元プロセスの完全な統一を保っています。wal-g
以降のサイクルでは、「復元 → 追従(catch up)→ 保存」という定常状態フローに戻ります。
高速化の必要性:並列処理の恩恵
PlanetScale は大量の並列処理を採用しており、その理由の一つがシャーディング特性にあります。各シャードには独立した Postgres プライマリが存在するため、堅牢なシステムをそれぞれのシャードで反復適用できます。
データ転送ステップ
- S3 から古いバックアップを復元
- S3 とプライマリのハイブリッド方式で追従(catch up)
- 新しいファイルを再度 S3 に送信
シェアリングの有効性比較
非シャーディング環境(例:単一 32TB データベース)
- 圧縮後サイズ:約 20 TB
- 総転送量:S3 取得 20,000 GB + S3 送信 20,001 GB = 約 40,030 GB
- 速度仮定(500 MBps):約 22 時間
- リスク:日 2 回のバックアップで作業が重なり、RPO(回復ポイント目標値)の達成が困難。
Neki シャーディング環境(8 シャード × 各 4TB)
- 総転送量は同等だが、8 つのバックアップノードで並列処理
- 所要時間:約 2.8 時間 に短縮(10 倍速い)
- スケーラビリティ:シャード数が増えるほど速度向上。
- 32 シャードなら 42 分 で完了。
- 100 テラバイト規模(100 シャード)でも、単一シャード同等の速度で処理可能。
バックアップは何に使われるのか?
バックアップは「データの安全性」だけでなく、日常運用の中核要素です。特に Metal データベース(ローカル NVMe 搭載)では以下の用途に不可欠です。
1. データベースのリサイズ
既存のノードを新しいサイズのインスタンス(例:i8g.xlarge → i8g.2xlarge)へ移行する際の手順:
- 新しい EC2 インスタンスセット(シャード数×3 など)を立ち上げる
- S3 から最新のバックアップを取得し、WAL を通じて追従させる
- 新旧ノードを同期させ、切り替え(switch-over)を実行
- 古いノードを除籍
所要時間:バックアップサイズと WAL 再生量により数分から数時間にわたります。
2. ノード障害時の復旧
平均サーバーライフサイクルが長い場合、大規模データベースでは特定の週や月にノード障害が統計的に発生しやすくなります。
- 障害対応フロー:
- 同じサイズのクラウドインスタンスを新規初期化
- 最近のバックアップから復元し、WAL を追従させる
- 元のプライマリのフォロワーとしてデータを同期
この新しいノードは、読み取りクエリ処理やフェイルオーバー中のプライマリとして即座に機能します。
MySQL についてはどうなのか?
PlanetScale では、Vitess クルーティング・シャーディングレイヤーを用いた大規模 MySQL データベースも運用しています。Postgres と仕組みは非常に似ていますが、以下の 3 つの点で異なります。
- ツール:Postgres の組み込み機能ではなく
を使用VTBackup - ログ方式:WAL ではなく、MySQL バイナリログレプリケーションを使用
- 追従方法:ハイブリッド方式(S3+プライマリ)ではなく、プライマリから直接行う
詳細は別途ブログ記事で解説していますが、基本コンセプトである「バックアップとリサイズの自動化」は共通しています。
まとめ:複雑性を透明化して「 effortless」に
お客様は、このように複雑な裏側のプロセスを意識する必要はありません。PlanetScale は以下の体験を提供します。
- 自動実行:バックアップ作成・スケジュール管理が自動化
- ワンクリック操作:データベースのリサイズも単一の API コールで完了
私たちはデータベース運用の細部まで深い愛情を注ぎ、複雑なオーケストレーションを透明性の高いシステムに変換し続けています。もしこの仕組みに魅了され、データベースエンジニアとしてのキャリアを目指すのであれば、PlanetScale には常に有能な方を募集しております。