ProgrammingDevOpsエンジニア / DBA

安全なSQLデータベースでのテーブル構造の変更(ALTER TABLE)を行うには、どのように実施すればダウンタイムとデータ損失のリスクを最小化できますか?

Hintsage AIアシスタントで面接を突破

答え。

問題の背景

テーブルのスキーマの変更は、アジャイルアプローチの普及とともに重要性を増しています。プロジェクトが進化し、要件が変更されるにつれて、カラムの追加、変更、削除が必要になることが必ずあります。本番環境のデータベースでは、そのような変更は特にリスクが高いです。

問題

構造の変更は以下のリスクを引き起こす可能性があります:

  • 長時間のロック
  • 古いデータの損失または不適切な移行
  • 外部制約、トリガー、アプリケーションのロジックの違反

特に、他のサービスによって頻繁に使用される大きなテーブル(数百万行)での変更は難しいです。

解決策

ALTER TABLEを利用した適切な手順での変更、データのバックアップ、スタンドでのテスト、ダウンタイムの制限を行うことが重要です。トランザクションの使用、段階的な移行、大規模な変更の前のバックアップを推奨します。高負荷のDBMSでは、"online"のALTERアルゴリズムをよく利用されます。

コード例:

-- デフォルト値を持つ新しいカラムの追加 ALTER TABLE orders ADD COLUMN status VARCHAR(20) DEFAULT 'new'; -- 新しいカラムへの段階的なデータ入力 UPDATE orders SET status = CASE WHEN shipped_at IS NOT NULL THEN 'shipped' ELSE 'pending' END;

主な特徴:

  • 最初に新しいカラムを作成し、次にデータを段階的に移行するのが望ましい
  • 大規模な操作はピーク時を避けて行う
  • 常にバックアップと自動テストを実施する

トリッキーな質問。

ALTER TABLEは原子性を持って実行されますか?

ほとんどの場合、いいえ:テーブルの変更には多くの時間がかかる可能性があります。障害が発生した場合、一部の変更がロールバックされる一方で、一部は残存してしまうことがあります。したがって、DDLコマンドに対するトランザクション保護を実装しているDBMSは限られています(例えば、PostgreSQL)。


INTEGERからVARCHARへのカラムタイプの変更はスムーズに行えますか?

常にではありません:カラムに新しいフォーマットに適合しない古いデータが存在する場合や、関連するオブジェクト(インデックス、トリガー、キー)がある場合、DBMSはタイプ変更を許可しないか、データが損傷する可能性があります。


ALTER TABLEは常にテーブル全体に排他ロックをかけるのですか?

DBMSによります:MySQLおよび古いバージョンのSQL Serverでは、ALTER操作はしばしばテーブル全体をロックしますが、最新のDBMSは"online DDL"をサポートし、ロック時間を短縮しています。

一般的なミスとアンチパターン

  • バックアップなしでの構造変更
  • スタンドでのテストなしでの大きなテーブルの移行
  • 依存関係の確認なしでのカラム名の変更(例えば、外部キー、手続き)
  • ピーク時に行う大規模なALTER

実際の例

ネガティブケース

DevOpsエンジニアは、ALTER TABLEを使用して3つの重要なテーブルに大規模な変更を加え、古いカラムを削除しました。これらのカラムに外部キーとトリガーが結びついていることを考慮しませんでした。ALTER作業中、データベースは20分間動作し続け、その間にサービスは必要なフィールドがなくなって停止しました。

利点:

  • 変更は仕様書に基づいて実施されました

欠点:

  • 一部のサービスが機能しなくなった
  • ビジネスのダウンタイムが30分近く続いた
  • 依存関係の回復や削除データの復旧が困難であった

ポジティブケース

アナリストは、段階的にカラムを追加する計画を立てました:最初にデフォルトのカラムを作成し、コピーにテストロードを注入し、その後実際のALTERを夜間に行い、すべての開発者に移行ウィンドウについて通知しました。

利点:

  • すべてが迅速かつ問題なく進んだ
  • データ損失とロックのリスクが減少した

欠点:

  • 追加のテストに時間がかかった