ダウンタイムを発生させずに、運用コードベース/データベーススキーマをどのように更新しますか?


42

ダウンタイムを引き起こすことなく、本番サーバーのコードベース/データベーススキーマを更新するためのテクニックは何ですか?


1
たくさんの人がこれを見落としているので、良い質問です。時は金なりであり、ダウンタイムは正当な理由に関係なく、エンドユーザーにとって決して良いものではありません。
ダン・マクグラス

@Dan McGrath:実際にダウンタイムが発生する可能性があると仮定すると、私は(通常)1年に4回だけ(ダウンタイム)ダウンし、毎回最大15分間(トラフィックがキューイングされる時間)のシステムで働いています。 ..データベースの変更は詳細に調査されています:)
Matthieu M.

2
これはdba.stackexchange.comにとって大きな質問になるでしょう。数時間でパブリックベータになります。
ラリーコールマン

回答:


20

一般に、この種の要件があった作業を行ったWebサイトはすべてロードバランサーの背後にあるか、個別のフェールオーバー場所がありました。このサンプルでは、​​少なくともSQL Serverの世界では、単一のロードバランサー、2つのWebサーバー(A&B)、2つのデータベースサーバー(M&N-通常、DBサーバーはログシップを介してリンクされている)があると仮定します)。

  1. ロードバランサーから切断されるWebサーバーA(したがって、すべての着信トラフィックはBに送られます)。
  2. ログ配布は停止します(DBサーバーMが最初に更新されます)。
  3. WebサーバーAを更新します。構成をDBサーバーMに向けます。
  4. 更新が機能したことをテストして確認します(通常、人々は直接IPアドレスにアクセスしています)。
  5. 既存のセッションが引き続きBに移動するようにロードバランサーを設定します。新しいセッションはAに移動します。
  6. Bのすべてのセッションが期限切れになるのを待ちます(30分以上になる場合があります。通常、トラフィックを監視し、1時間の休憩を予定しています)。
  7. BおよびNを更新します。
  8. 更新が機能したことをテストおよび検証します。
  9. ログ配布を再度セットアップし、動作をテストします。
  10. ロードバランサーを通常の動作に設定します。

非常に複雑なWebアプリケーションでは、ステップ1から5として説明されるものは一晩中かかり、時間と緊急連絡先番号が記載された50ページのExcelスプレッドシートになります。このような状況では、システムの半分の更新は午後6時から午前6時にスケジュールされ、ユーザーはシステムを利用できます。DRサイトの更新の処理は通常、次の夜に予定されています。最初の日が何も中断しないことを願っています。

アップタイムが必要な場合、パッチは最初にQA環境でテストされます。これは理想的には本番と同じハードウェアです。混乱が見られない場合は、通常の週末(通常は週末)に適用できます。


7
DB MとDB Nからの新しいデータのマージをどのように提案しますか?どちらにも、他方にはない新しい、更新、および削除されたレコードがあります。
sixtyfootersdude

@タングレナ、上記のコメントに答えてもらえますか?
シノ

9

典型的なデータベース(たとえばOracle)の場合、クエリを並行して実行しながらデータベーススキーマを変更することができます。ただし、いくつかの将来の計画が必要です。

変更が適用されるためのいくつかの制約があります。

  • 既存のコードで動作するはずです。つまり、コードはスキーマの古いバージョンと新しいバージョンの両方を処理する必要があります。
  • トランザクションが停止するほど大きな負荷がDBにかかることはありません(私はあなたを見ていますCREATE INDEX
  • データが失われることはありません(テーブルを削除して再作成することはできません)

スキーマに下位互換性を持たせるために、通常、列を追加または変更できます。既存のコードで使用されなくなった場合のみ、何かを削除できます。

コードが透過的に変更を処理できない場合は、データベースを変更する前にコードを変更してください。

フォワードプランニングに関する簡単なアドバイス:DBリクエストでは常に列名を明示的に使用します(使用しないでくださいSELECT * FROM)。これにより、古いリクエストに新しい列が表示されなくなります。


1
実際、将来の計画と適応性のために、select * fromは列を手動でリストするよりもはるかに優れています。明示的な列名を使用すると、ほとんどの場合、多くの技術的負債が生じます。コードが新しい列から壊れている場合、コードは既に壊れています。
モルグ。

@モルグ:そうでもない。セキュリティのために、バインド変数を使用する必要があります。私が使用するフレームワークでは、(少なくとも)書き込む変数を提供する必要があり、出力列と同じ数の変数が必要select *です。つまり、新しい列が追加されます(書き込み先の変数がないため)。もちろん、これは強く型付けされた言語を使用した結果かもしれません。
マチューM.

はい、確かに、select *を回避するための追加のセキュリティはありません。強く型付けされた言語とは関係がなく、非常に悪いデザインと関係があります。フレームワークが変更をシームレスに処理できない場合、それは役に立ちません。列を変更しても、アプリケーションの動作が停止することはありません。すると壊れます。どちらがより信頼性が高く安全であるかについて疑問はないと思います。
モルグ。

@Morg .: select *より信頼性が高く安全な方法がわかりません。使用していselect one, two from ...た場合は、とのみを使用oneしていましたtwothirdがテーブルに追加された場合、(ここでは)使用できないので、取得する理由はありません。突然使用する必要がある場合は、コードを変更するため、この時点でクエリを変更することもできます。
マチューM.

@Morg .:まあ、おそらく私たちの経験が異なるために、私たちはお互いに過去を話し合っているようです。私は、パフォーマンスが最重要プロパティである製品に取り組んでいます。これは、select可能な限り選択的である必要があることを意味します(そして、インデックスでカバーされます)。申し訳ありませんが、あなたが説明しているアプローチは、これらの製品の完全な失敗でした。
マチューM.

5

すべてのシステムができるわけではありませんが、それをサポートする方法でセットアップする必要があります。

たとえば、数年前にアップグレードを支援した主要なシステムの1つは24時間365日利用できるはずです。オフサイトのユーザーインターフェイスレイヤーとビジネスレイヤーの間の純粋な通信層を含む、複数の層で構成されていました。通信層のコーディング方法により、ビジネス層またはDBスキーマに対する将来の変更は、実際に停止することなく実装できます。最悪のシナリオでは、変更が有効になると、ユーザーは10〜30秒の一時停止を経験します。

変更がビジネスレイヤへの純粋なコード変更である場合、わずか数ミリ秒の遅延でキューに入れて「循環」させることができます。

これは次の理由で実行できます。

  • 通信層はメッセージを保持できます。これにより、UIを停止することなく、UIレイヤー以外の層のいずれかで実際に停止することができました。
  • MVDBが処理するビジネスレイヤーはUniDataと呼ばれます。これにより、すべてのコードがメモリに保持されます。コードをコンパイルした後、コマンドを使用して新しいオブジェクトコードを強制的にメモリに入れ、古いコードを置き換えることができます。

他の手法には、既存のシステムの別のミラーへのトランザクションの複製が含まれます。更新を1つに適用し、更新と切り替えの間で行われたすべてのトランザクションを切り替えて再生します。ただし、システムに応じてYMMV。


1

組み込みデータベースシステムと組み込みシステムの世界とは異なる視点があります。組み込みシステムにはさまざまなネットワーク/通信インフラストラクチャ機器が含まれており、この分野ではしばしば99.999%(5秒)のアップタイムを示しています。

私たち(McObject)は、eXtremeDB High Availabilityを含む組み込みデータベースシステム製品のeXtremeDBファミリのベンダーです。

まず、「組み込みデータベース」とは、データベースシステムがアプリケーションコードとコンパイルおよびリンクされたライブラリであることを意味することを理解してください。その意味では、アプリケーションに「組み込まれ」ます。

eXtremeDBの高可用性では、アプリケーションのMASTERインスタンス(1つまたは複数のプロセスである可能性があります)およびアプリケーションの1つまたは複数のREPLICAインスタンスがあります。レプリカがマスターへの接続を確立すると、「初期同期」と呼ばれるプロセスを介してマスターのデータベースのコピーを受け取ります。これは、マスターアプリケーションが作業を継続している間に行うことができます。同期化されると、レプリケーションを通じてマスターのトランザクションを受け取ります。したがって、レプリカには常に現在のデータがあり、マスターに障害が発生した場合に(フェールオーバーと呼ばれるプロセスを介して)引き継ぐことができます。

初期同期の機能の1つは、「バイナリスキーマの進化」と呼ばれます。簡単に言えば、これは、レプリカのデータベースにデータを取り込むプロセスが、レプリカのデータベーススキーマとマスターのデータベーススキーマの違いに対応することを意味します。

実際には、これは、新しいバージョンのアプリケーション(新しい/ドロップされたテーブル、新しい/ドロップされた/変更されたフィールド、新しい/ドロップされたインデックス)を構築し、その新しいバージョンのアプリケーションをマスターにアタッチし、それを引き起こすことができることを意味します新しいレプリカになる新しいレプリカ(つまり、新しいレプリカへのフェールオーバーを強制して、マスターになり、古いマスターがシャットダウンします)。これで、システムの可用性を中断することなく、アプリケーションをバージョンNからN + 1に移行しました。これで、古いマスターと他のレプリカをバージョンN + 1にアップグレードできます。

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