0Pricing
SQL Academy · レッスン

ディザスタリカバリ計画

RPO、RTO、ランブックについて学びます

「ディザスタリカバリ計画」はCoddyKit上の無料SQL Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSQL Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 SQL Academyコースには全4レッスンが含まれています。

ディザスタリカバリとは

ディザスタリカバリ(DR)とは、自然災害や人的災害の発生後に、重要なテクノロジーインフラストラクチャとシステムを復旧できるようにするためのポリシー、ツール、手順の総称です。

データベースの文脈では、DR計画によって、ハードウェア障害、誤ったデータ削除、ランサムウェア攻撃、データセンターの停止などが発生した後も、データを安全に保ち、許容可能な時間内にシステムをオンラインへ戻せるようにします。

目標復旧時点(RPO)

RPOは、時間で測定した、許容できるデータ損失量の最大値を定義します。RPOが1時間の場合、災害発生時刻の少なくとも1時間前までのデータを復旧できなければなりません。

RPOを短くするには、より頻繁なバックアップまたは継続的なレプリケーションが必要です。バックアップ履歴をクエリして、RPOの目標を満たしていることを確認できます。

-- Check the last backup time and calculate data loss window
SELECT
  backup_id,
  backup_type,
  started_at,
  finished_at,
  EXTRACT(EPOCH FROM (NOW() - finished_at)) / 3600 AS hours_since_backup
FROM backup_log
WHERE status = 'SUCCESS'
ORDER BY finished_at DESC
LIMIT 5;

目標復旧時間(RTO)

RTOは、災害発生後にシステムをオフラインにしておける許容時間の最大値を定義します。RTOが4時間の場合、障害発生から4時間以内にデータベースを完全に稼働させなければなりません。

RTOは、スタンバイサーバー、フェイルオーバーの自動化、リストア手順に関する判断を左右します。リストアにかかった時間を継続的に記録すると、RTOを達成できるかどうかを予測しやすくなります。

-- Track restore durations to validate RTO compliance
SELECT
  restore_id,
  triggered_at,
  completed_at,
  EXTRACT(EPOCH FROM (completed_at - triggered_at)) / 60 AS restore_minutes,
  CASE
    WHEN EXTRACT(EPOCH FROM (completed_at - triggered_at)) / 3600 <= 4
    THEN 'WITHIN RTO'
    ELSE 'RTO BREACHED'
  END AS rto_status
FROM restore_log
ORDER BY triggered_at DESC;

RPOとRTO — 重要な違い

この2つの指標は混同されがちです。次のように覚えると簡単です。

  • RPO = どれだけのデータ損失まで許容できるか(過去を振り返る指標で、災害前の時間で測定)
  • RTO = どれだけの時間、停止を許容できるか(将来を見通す指標で、災害後の時間で測定)

この2つによってリカバリウィンドウが定まり、バックアップ頻度、レプリケーション戦略、インフラストラクチャ予算に直接影響します。

-- Store RPO and RTO targets per database in a DR configuration table
CREATE TABLE dr_config (
  db_name       VARCHAR(100) PRIMARY KEY,
  rpo_minutes   INT NOT NULL,
  rto_minutes   INT NOT NULL,
  tier          VARCHAR(20) CHECK (tier IN ('CRITICAL', 'HIGH', 'MEDIUM', 'LOW')),
  updated_at    TIMESTAMP DEFAULT NOW()
);

INSERT INTO dr_config (db_name, rpo_minutes, rto_minutes, tier) VALUES
  ('orders_db',    15,   60, 'CRITICAL'),
  ('analytics_db', 120, 240, 'MEDIUM'),
  ('archive_db',   480, 480, 'LOW');

バックアップの種類

主なバックアップ戦略は3つあり、それぞれ速度とストレージ容量のバランスが異なります。

  • フルバックアップ:データベース全体の完全なスナップショットです。作成には最も時間がかかりますが、リストアは最も速く行えます。
  • 差分バックアップ:直前のフルバックアップ以降の変更のみを保存します。作成とリストアの速度はどちらも中程度です。
  • 増分バックアップ:種類を問わず、直前のバックアップ以降の変更のみを保存します。作成は最も速い一方、リストアには複数のファイルが必要なため最も遅くなります。

多くのDR戦略では、RPOとストレージコストのバランスを取るために、週1回のフルバックアップと毎日の増分バックアップを組み合わせます。

-- Log each backup with its type for audit and recovery planning
CREATE TABLE backup_log (
  backup_id   SERIAL PRIMARY KEY,
  db_name     VARCHAR(100) NOT NULL,
  backup_type VARCHAR(20) CHECK (backup_type IN ('FULL', 'DIFFERENTIAL', 'INCREMENTAL')),
  started_at  TIMESTAMP NOT NULL,
  finished_at TIMESTAMP,
  size_mb     NUMERIC(12, 2),
  status      VARCHAR(20) DEFAULT 'IN_PROGRESS'
);

INSERT INTO backup_log (db_name, backup_type, started_at, finished_at, size_mb, status) VALUES
  ('orders_db', 'FULL',        '2024-06-01 01:00:00', '2024-06-01 02:15:00', 45200, 'SUCCESS'),
  ('orders_db', 'INCREMENTAL', '2024-06-02 01:00:00', '2024-06-02 01:08:00',   320, 'SUCCESS'),
  ('orders_db', 'INCREMENTAL', '2024-06-03 01:00:00', '2024-06-03 01:07:00',   290, 'SUCCESS');

ポイントインタイムリカバリ(PITR)

ポイントインタイムリカバリを使うと、最後にバックアップを取得した時点だけでなく、データベースを特定の任意の時点にリストアできます。これは、ベースバックアップに対してトランザクションログ(PostgreSQLではWAL)を再生することで実現します。

PITRは、既知の時点で発生した誤ったデータ破損や削除から復旧する必要がある場合に不可欠です。問題を引き起こした事象が発生する直前の状態にリストアできます。

-- Record WAL archive events for PITR tracking
CREATE TABLE wal_archive_log (
  segment_name  VARCHAR(200) PRIMARY KEY,
  archived_at   TIMESTAMP DEFAULT NOW(),
  size_bytes    BIGINT,
  storage_path  TEXT
);

-- Find all WAL segments archived within a recovery window
SELECT
  segment_name,
  archived_at,
  ROUND(size_bytes / 1024.0 / 1024.0, 2) AS size_mb
FROM wal_archive_log
WHERE archived_at BETWEEN '2024-06-03 09:00:00' AND '2024-06-03 11:00:00'
ORDER BY archived_at;

スタンバイデータベースとレプリケーション

スタンバイ(レプリカ)データベースは、別のハードウェア上で稼働し、プライマリデータベースの更新を継続的に反映するコピーです。DRにおいて、次の2つの目的を果たします。

  • ホットスタンバイ:読み取りクエリを受け付けられ、数秒でフェイルオーバーできます(RTOはほぼゼロです)。
  • ウォームスタンバイ:同期状態に保たれますが、トラフィックは処理しません。フェイルオーバーには数分かかります。

レプリケーション遅延の監視は重要です。遅延しているレプリカがあると、実際のRPOは想定よりも悪化します。

-- Monitor replication lag on a PostgreSQL primary
SELECT
  client_addr,
  application_name,
  state,
  sent_lsn,
  replay_lsn,
  (sent_lsn - replay_lsn) AS lag_bytes,
  EXTRACT(EPOCH FROM (NOW() - reply_time)) AS seconds_since_reply
FROM pg_stat_replication
ORDER BY lag_bytes DESC;

ランブック:リカバリ手順を文書化する

ランブックとは、ディザスタリカバリの際にオペレーターが従う、手順を追った指示を文書化したものです。ランブックがなければ、経験豊富なDBAでもプレッシャーの下で高くつくミスを犯します。

優れたDRランブックには、連絡先、影響を受けるシステム、実行する正確なコマンド、各手順で想定される出力、リカバリに失敗した場合のロールバック手順が含まれます。ランブックのメタデータをデータベースに保存すると、バージョン管理や使用状況の監査に役立ちます。

-- Store runbook metadata in the database for audit tracking
CREATE TABLE runbook (
  runbook_id   SERIAL PRIMARY KEY,
  title        VARCHAR(200) NOT NULL,
  scenario     VARCHAR(100),
  version      VARCHAR(20) DEFAULT '1.0',
  last_tested  DATE,
  owner        VARCHAR(100),
  doc_url      TEXT
);

INSERT INTO runbook (title, scenario, version, last_tested, owner, doc_url) VALUES
  ('Full Database Restore from S3', 'total_loss',     '2.1', '2024-05-15', 'dba_team', 'https://wiki.internal/dr/full-restore'),
  ('Failover to Hot Standby',       'primary_down',   '1.4', '2024-04-20', 'dba_team', 'https://wiki.internal/dr/failover'),
  ('PITR to Specific Timestamp',    'data_corruption','1.2', '2024-03-10', 'dba_team', 'https://wiki.internal/dr/pitr');

ランブックの実行を記録する

ランブックを実行するたびに、実際の災害時であっても訓練であっても、記録する必要があります。実行ログによって、実際のリカバリにかかった時間を測定してRTOを検証し、時間がかかる手順やエラーが発生しやすい手順を特定し、監査人にコンプライアンスを示すことができます。

-- Log each runbook execution for RTO validation and audit
CREATE TABLE runbook_execution (
  execution_id  SERIAL PRIMARY KEY,
  runbook_id    INT REFERENCES runbook(runbook_id),
  triggered_by  VARCHAR(100),
  is_drill      BOOLEAN DEFAULT FALSE,
  started_at    TIMESTAMP NOT NULL,
  completed_at  TIMESTAMP,
  outcome       VARCHAR(20) CHECK (outcome IN ('SUCCESS', 'PARTIAL', 'FAILED'))
);

-- Report average restore time per runbook
SELECT
  r.title,
  COUNT(*) AS executions,
  ROUND(AVG(EXTRACT(EPOCH FROM (e.completed_at - e.started_at)) / 60), 1) AS avg_minutes,
  MAX(EXTRACT(EPOCH FROM (e.completed_at - e.started_at)) / 60) AS max_minutes
FROM runbook_execution e
JOIN runbook r ON r.runbook_id = e.runbook_id
WHERE e.outcome = 'SUCCESS'
GROUP BY r.title;

DRテスト:定期的な訓練

一度もテストされていないDR計画は、計画ではなく願望にすぎません。定期的な訓練は、チームが定義されたRTO内で実際にランブックを実行でき、バックアップを確実にリストアできることを確認するために必須です。

データベースで訓練のスケジュールと実施状況を管理すると、監査証跡を作成でき、テストの期限を過ぎているランブックを見つけやすくなります。

-- Find runbooks that have not been drilled in over 90 days
SELECT
  r.runbook_id,
  r.title,
  r.scenario,
  MAX(e.completed_at) AS last_drill,
  CURRENT_DATE - MAX(e.completed_at::DATE) AS days_since_drill
FROM runbook r
LEFT JOIN runbook_execution e
  ON e.runbook_id = r.runbook_id
  AND e.is_drill = TRUE
  AND e.outcome = 'SUCCESS'
GROUP BY r.runbook_id, r.title, r.scenario
HAVING MAX(e.completed_at) IS NULL
    OR CURRENT_DATE - MAX(e.completed_at::DATE) > 90
ORDER BY days_since_drill DESC NULLS FIRST;

バックアップ保持ポリシー

保持ポリシーは、バックアップをどのくらいの期間保管するかを定義します。すべてのバックアップを永久に保持するとストレージを無駄に消費し、早く削除しすぎるとRPOやコンプライアンス要件に違反します。

一般的なポリシーは、増分バックアップを7日間、週次のフルバックアップを4週間、月次のフルバックアップを12か月保持するというものです。バックアップログに対するSQLクエリを使って、保持を適用および監査できます。

-- Identify backups that are outside their retention window and ready to purge
SELECT
  backup_id,
  db_name,
  backup_type,
  finished_at,
  CURRENT_DATE - finished_at::DATE AS age_days,
  CASE backup_type
    WHEN 'INCREMENTAL' THEN 7
    WHEN 'DIFFERENTIAL' THEN 28
    WHEN 'FULL'         THEN 365
  END AS retention_days,
  CASE
    WHEN (CURRENT_DATE - finished_at::DATE) >
         CASE backup_type
           WHEN 'INCREMENTAL' THEN 7
           WHEN 'DIFFERENTIAL' THEN 28
           WHEN 'FULL'         THEN 365
         END
    THEN 'PURGE'
    ELSE 'KEEP'
  END AS action
FROM backup_log
WHERE status = 'SUCCESS'
ORDER BY finished_at;

クイックチェック

RPOとRTOの定義についての理解度を確認しましょう。

まとめ:ディザスタリカバリ計画

このレッスンでは、データベースのディザスタリカバリ計画の基礎を学びました。

  • RPOは、時間で表した許容可能なデータ損失の最大値を定義します。RPOを短くするには、より頻繁なバックアップまたは継続的なレプリケーションが必要です。
  • RTOは、システムをどれだけ早く復旧する必要があるかを定義します。RTOを短くするには、ホットスタンバイと自動フェイルオーバーが必要です。
  • バックアップの種類であるフル、差分、増分には、それぞれストレージ容量、作成速度、リストア速度の間で異なるトレードオフがあります。
  • PITR(Point-in-Time Recovery、ポイントインタイムリカバリ)はトランザクションログを使用して任意の正確な時点まで復旧し、誤った変更からデータを保護します。
  • ランブックには復旧手順のすべての手順を記録します。実行結果をログに記録することで、実際の運用でRTOを達成できることを検証できます。
  • 定期的なDR訓練は、バックアップから復元できることと、実際のプレッシャーの下でチームがRPOおよびRTOの目標を達成できることを確認する唯一の方法です。
  • 保持ポリシーでは、ストレージコストとコンプライアンスおよび復旧の要件のバランスを取ります。

十分にテストされたDR計画は、データベースチームが行える投資の中でも特に価値の高いものです。

よくある質問

「ディザスタリカバリ計画」レッスンは無料ですか?

はい。「ディザスタリカバリ計画」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、SQL Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 SQL Academyコースには全4レッスンが含まれています。

「ディザスタリカバリ計画」で何を学びますか?

RPO、RTO、ランブックについて学びます ブラウザで直接実行するハンズオンコードでSQL Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

SQL Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのSQL Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「ディザスタリカバリ計画」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このSQL Academyレッスンでコードを書いて実行できますか?

はい。すべてのSQL Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 論理バックアップと物理バックアップ
  2. ポイントインタイムリカバリ
  3. 復元をテストする
  4. ディザスタリカバリ計画
← SQL Academyに戻る