複数のアプリインスタンスでデータベースの移行を安全に実行するにはどうすればよいですか?


10

高速(1秒未満)と低速のデータベース移行(> 30秒)の両方が混在するアプリケーションがあります。現在、データベースの移行をCIの一部として実行していますが、CIツールはアプリのデータベース接続文字列をすべて(複数の環境で)認識している必要があるため、理想的ではありません。このプロセスを変更して、アプリケーションが起動時に独自のデータベース移行を実行するようにします。

ここに状況があります:

このアプリケーションの複数のインスタンスがあり、約5つが本稼働しています。それらを呼び出しましょうnode1, ..., node5。各アプリは単一のSQL Serverインスタンスに接続し、ローリングデプロイを使用していません(すべてのアプリは私の知る限り同時にデプロイされています)。

問題:長期にわたる移行があるとしましょう。この場合、node1は開始してから、マイグレーションの実行を開始します。さて、node4開始し、長期実行の移行がまだ完了していないためnode4、移行の実行も開始します->データ破損の可能性はありますか?この問題をどのように防止しますか、または問題は心配するほど重要ですか?

私はこの問題を分散ロックで解決しようと考えていました(etcdそれらを使用するか、それに沿って何かを使用します)。基本的に、すべてのアプリがロックを取得しようとし、そのうちの1つだけがロックを取得して移行を実行してから、ロックを解除します。残りのアプリが起動してクリティカルセクションに入ると、すべての移行がすでに実行されているため、移行スクリプトは終了します。

しかし、私の直感は「これはやり過ぎです。もっと簡単な解決策があるはずです」と言っているので、他の誰かがもっと良いアイデアを持っているかどうかを確認するためにここに尋ねると思いました。


1
「移行ステータス」テーブルをグローバル/分散ロックとして使用するのはどうですか?単一の行は、移行が現在アクティブであるかどうか、およびおそらく最後に実行された移行を示します。
Bart van Ingen Schenau 2017

アプリを非同期でデプロイする必要がありますか?
Ben

回答:


4

SQLサーバーについて言及したので、以前のDBA.SEの投稿によると、スキーマの変更をトランザクションに入れることができます(すべきです)。これにより、他のDBへの同時書き込みと同じように移行を設計できます。トランザクションを開始し、トランザクションが失敗すると、ロールバックします。これにより、最悪のデータベース破損シナリオの少なくとも一部が防止されます(ただし、列やテーブルの削除などの破壊的な移行手順がある場合、トランザクションだけではデータ損失は防止されません)。

これまでのところ、migrationsすでに適用されている移行が登録されているテーブルも必要になると思います。これにより、アプリケーションプロセスは、特定の移行がすでに適用されているかどうかを確認できます。次に、「SELECT FOR UPDATE」を使用して、次のような移行を実装します(疑似コード)。

  • 取引を開始する
  • SELECT FROM Migrations FOR UPDATE WHERE MigrationLabel='MyMigration42'
  • 前のステートメントが値を返す場合、トランザクションを終了します
  • 移行を適用する(失敗した場合はロールバックし、失敗をログに記録してトランザクションを終了する)
  • INSERT 'MyMigration42' INTO Migrations(MigrationLabel)
  • トランザクションを終了する

これにより、「移行は既に適用されました」テストにロックメカニズムが直接組み込まれます。

この設計では-理論的には-どのアプリケーションが実際に適用するのかを移行ステップに認識させないようにすることができます-ステップ1はapp1、ステップ2はapp2、ステップ3はアプリ3、ステップ4はapp1によって適用される可能性があります再び、など。ただし、他のアプリインスタンスが使用されている限り、移行を適用しないこともお勧めします。質問で述べたように、並列展開はすでにこの制約を考慮している場合があります。


1

多分あなたは、複数のノードでデータベースの移行をサポートするライブラリを見つけることができます。

Javaの世界には2つのライブラリーがあり、どちらも必要なものをサポートしています。

  • LiquibaseFAQから:Liquibaseは分散ロックシステムを使用して、一度に1つのプロセスのみがデータベースを更新できるようにします。他のプロセスは、ロックが解除されるまで単に待機します。
  • Flywayダウンロードページから:複数のノードを並行して安全に✓

おそらく、Javaや他の言語用の他のツールもあるでしょう。


このようなツールを使用できない(または使用したくない)場合、テーブルをロックとして、または移行ログとして使用できます。例については、Doc Brownsの回答を参照してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.