ダウンタイムなしでのスキーマ変更とライブデータベースへのデータ移行のベストプラクティス


43

ダウンタイムなしでライブデータベースのスキーマをどのように変更しますか?

たとえば、すべてが特定のユーザーに関連付けられている、メールアドレスなどのさまざまなユーザーデータを含むテーブルを持つPostgreSQLデータベースがあるとします。電子メールアドレスを新しい専用テーブルに移動する場合は、スキーマを変更してから、電子メールデータを新しいテーブルに移行する必要があります。元のテーブルへの書き込みを停止せずにこれを行うにはどうすればよいですか?確かに、古いテーブルから新しいテーブルにデータが上書きされる間、新しいデータは引き続き古いテーブルに書き込まれ、失われますよね?

この問題はかなり頻繁に発生すると思いますが、それを処理するための標準的なソリューションが見つかりません。

この記事でこの問題を扱いますが、手順3を本当に理解していませんでした。彼は両方のテーブルに書き込み、古いデータを最初のテーブルから新しいテーブルに移行するように言っています。古いデータのみを移行していることをどのように確認しますか?

HerokuでPostgreSQLを使用しています。)


2
Facebook は、 MySQL用にこれを行うツール開発しました
ニックチャマス

2
K.スコットアレンは、ここでスキーマバージョンを管理するシステムについて書いています。バージョン対応のスキーマ展開用のオープンソースツールであるDbUpdaterを作成しました。もっとここに- http://www.tewari.info/dbupdater

@NickChammasそれを共有してくれてありがとう。質問がたくさんあります。より詳細なチュートリアル、できればビデオで、ビットログ、非クラスター化インデックスなどについて説明し、次のような質問に答えてください。テーブルを直接。2.コピーフェーズはいつ終了しますか?これらは私が持っているほんのいくつかの質問であり、私はそれを読み始めたばかりです。
サンディーパンナス

@SandeepanNath-申し訳ありませんが、私はFacebookのツールにそれほど詳しくないので、他のリソースを紹介することはできません。私はそれについての発表を読んで、何年も前にコメントを投稿しましたが、私はそれを使ったことがありません。
ニックチャマス

回答:


27

あなたはすでにあなたの答えをほとんど持っています:

  1. 新しい構造を並行して作成します
  2. 両方の構造への書き込みを開始します
  3. 古いデータを新しい構造に移行する
  4. 新しい構造の書き込みと読み取りのみ
  5. 古い列を削除する

ステップ3、(1つのトランザクションで)このようなものを使用します。

まだ存在しないものを挿入します。

INSERT INTO new_tbl (old_id, data)
SELECT old_id, data
FROM   old_tbl
WHERE  NOT EXISTS (SELECT * FROM new_tbl WHERE new_tbl.old_id = old_tbl.old_id);

その間に変更された内容を更新します。

UPDATE new_tbl
SET    data  = old.data
USING  old_tbl
WHERE  new_tbl.old_id = old_tbl.old_id
AND    new_tbl.data IS DISTINCT FROM old_tbl.data;

新しいデータは、両方の場所で同一であるため、変更されません。


この回答を提案したシナリオを理解しようとする際にいくつか質問があります-1. dbの変更の開始とともにコードの変更がデプロイされますか?2.なぜ両方の構造に書き込む必要があるのですか?3.なぜ新しい構造を最初に立ち上げ、次に既存のデータを移行し、次に新しい構造にデータを追加するコード変更をデプロイできないのですか?4.なぜないのか(最初のクエリ)を見つける必要があるのはなぜですか?複数回の挿入を提案していますか?
サンディーパンナス

2
@SandeepanNath、あなたのコメントに質問3に答える:あなた()これまで、(b)に移行データを新しい構造を持ち出す場合、(c)は、その後、代わりに古いの新しい構造への書き込みデータにコードを変更するので、すべてのステップbとステップcの間で行われたデータ変更は古い構造にのみ存在します。問題は、ダウンタイムなしでスキーマを変更する方法でした。 この回答を注意深く読んでください。
ワイルドカード
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.