1

問題: コミットが遅いシーケンシャル データベース移行スクリプトを処理する方法 / gerrit。

セットアップは次のとおりです。

  • データベース テーブルの継続的な開発は、連続した名前 (12.sql、13.sql、14.sql など) のファイルを追加することによって行われます。
  • データベースにバージョン番号が設定されている
  • 移行ツールはファイルに対してバージョンをチェックし、未処理のデータベース移行があるかどうかを確認します

このアプローチの主な問題 (それ以外の場合はうまく機能します) は、2 人の開発者が同時に移行スクリプトを追加すると、最後にコミットした開発者がマージの競合を起こすことです。Subversion (これまで使用してきました) では、これはツリーの競合であり、コミッターは最後のアクションとしてそのファイルを元に戻し、新しいファイル名で追加することで処理しました。私たちはトランクでこのような作業を行っていたので、彼らは通常、最後の迅速なアクションとしてファイル名を修正することができました.

git に移行しているため、代わりに競合がファイル内の差分として表示されるため、コミットされた 2 つのファイル (他のファイルと一緒に異なるコミット パッケージの一部である可能性があります) を分離するのが難しくなります。さらに、コード レビューに gerrit を使用しているため、ファイルをメインの git リポジトリにプッシュしてから取得するまでに遅延が発生し、時々このシナリオが発生します。

  1. 移行をプッシュする
  2. コード レビュー後に Gerrit が競合する
  3. ファイルの名前を変更して競合を修正し、新しいコミットをプッシュします (これは再度確認する必要があります)。
  4. これがコードレビューされる前に、誰かがなんとか新しい移行を取得したため、Gerrit は再び競合します。
  5. ファイルの名前を変更して競合を修正し、新しいコミットをプッシュします (これは再度確認する必要があります)。
  6. 運が良く、Gerrit が移行を正常に送信できるまで、4 から繰り返します。

この状況を解決する最善の方法は何ですか?

4

3 に答える 3

4

私は、liquibaseを使用してデータベースの移行を管理しています。

XML 構文を使用して、各「変更セット」をデータベースに記述します。これは採用の障壁になる可能性がありますが、さまざまな開発者からの貢献を同じファイルにマージするのがはるかに簡単になることがわかりました。

<changeSet id="bob-20130115-1" author="bob">
    <createTable tableName="commontable">
       ..
       ..
    </createTable>
</changeSet>

<changeSet id="tom-20130115-1" author="tom">
    <addColumn tableName="commontable">
        <column name="newcolumn" type="varchar(255)"/>
    </addColumn>
</changeSet>

liquibase を使用する 2 つ目の利点は、ロールバックがサポートされていることです。競合が発生した場合は、変更セットを元に戻し、最後の安定版リリースに戻し、移行ファイルを修正して、新しい更新を実行できます。

ツールを切り替える余裕がない場合は、DEV 中の各移行を「変更セット」として扱うという liquibase のアプローチを採用することをお勧めします。反復ごとに 1 つの移行ファイルを使用し、各開発者の貢献の開始と終了にコメントを追加します。マージの競合が発生した場合は、SQL を書き直そうとしないでください。代わりに、ある開発者の変更が他の開発者の変更より前または後に来るように順序を変更してください。(他の開発者に別のファイルを作成させるというアプローチは有効ですが、実際には実装が難しいことがわかりました.3番目の開発者が後で来て、シーケンスの次の番号と競合します....)

ロールバック機能なしで統合環境を管理するのは難しいです....データベースを毎回ゼロから再構築する以外に簡単な方法を知りません。おそらく唯一の効果的な方法は、VonC のアドバイスに従い、データベース チェンジャーの数を最小限に抑えることです。

ノート:

  • 独自のデータベースを使用する各開発者は当然のことです。移行ツールを使用しているため、異論はありません。特にスキーマを吹き飛ばして再構築する必要がある場合に、問題が単純化されます。また、「テスト データ」の課題に対処することも余儀なくされます.... テスト データが単一のデータベース インスタンスにあるプロジェクトに取り組んでいると、頭が痛くなります....
  • 私は最近、SQL Alchemy migrateが liquibase と同じロールバック機能を備えていることを発見しました。移行ごとにロールフォワード スクリプトとロールバック スクリプトの両方を作成する必要があります。
于 2013-01-15T20:12:21.133 に答える
2

私は1つの解決策としてLiquibaseを2番目にしています。Mark O'Connor IMHOがあまりよく指摘しなかったLiquibaseの特性の1つは、Liquibaseが、適用されたチェンジセットとアプローチで最後に適用された変更のリストを保持していることです。

したがって、(変更識別子が衝突しない限り)ブランチは問題になりません。Liquibaseは、XML内で順番に適用されていない未解決の変更セットをすべて適用するだけです。衝突を検出する機能として、Liquibaseはチェンジセットのソースコード自体のMD5ハッシュも保存するため、変更「XY」自体の内容が変更されたことも検出できます。このような場合は、何が悪かったのかを手動で把握し、サードパーティによって適用された後に変更セットを変更しないように開発者の同僚に教える必要があります。

liquibaseのような新しいデータベースバージョン管理ツールを切り替えたり導入したりしたくない場合は、カスタムアプローチをこの方向に簡単に拡張できると思います。適用された変更のリストを維持するだけで、ファイル名が一致しない限り、ブランチにうまく取り組むことができます。

于 2013-01-16T15:17:42.443 に答える
0

2 人の開発者が同時に移行スクリプトを追加する

彼らは独自のブランチで変更を行い、Gerrit で別のレビューをトリガーする必要があります。
インテグレーター (または 2 人の開発者のうちの 1 人) が、2 つの開発作業をマージしてレビューする責任を負います。

それ、または「dev 1」がパッチを取得する必要がある場合に「dev 2」をチェックせずに「dev 1」が何もプッシュしないようにするために、2つの間の通信を改善する必要があります(「dev 2」のパッチを表す) work) "dev 1" のワーキング ツリーの最初。

于 2013-01-15T13:51:51.893 に答える