PostgreSQLコードのバージョン管理とデプロイ

数百のデータベースと数千のストアドプロシージャ。 24x7の高負荷の状態で迅速にロールバックし、死なない機能を備えた、多くのサーバーですべてを作成、テスト、展開する方法は? 面白い? 猫へようこそ!



画像



すでにご存知のように、 Avitoのすべての広告はPostgreSQL に存在します。 このデータベースの機能は、データレベルだけでなく、ストアドプロシージャ、トリガー、関数を通じてこのデータへのアクセスを提供する独自のAPIの作成にも基づいて、非常に優れた機能を提供します。 この構造全体で作業する場合、いくつかの変更が必要になることがよくあります。 そして最も単純なケースでは、開発者が1つのクライアントと1つのデータベースを扱う場合、更新プロセスは非常に単純に見えます。変更、移行スクリプト、そしてそれだけです。 しかし、そのような状況はまれであり、多くの場合、製品の顧客とデータベースは数百になります。 したがって、通常のデータベースライフサイクルでは、コードをバージョン管理するメカニズムが不可欠です。



この記事では、Avitoで実装したデータベース内のコードをバージョン管理する2つの方法について説明します。 この情報が役立つ場合があります。 まず、少しのコンテキスト。



Avitoは:





最初のタスク:











最初のバージョン管理オプション



私たちが思いついた最初のオプションは、辞書によるバージョン管理です。



詳細





列名







説明



















役職



その中で

実施された

保存の開発

手順







ロケーションID修正







fn_name







役職

保存された

を含む手順

スキーム







core.location_save







fn_md5







ハッシュ量

(md5)コード

保存された

手順







0539f31fee4efd845a24c9878cd721b2







ver_id







バージョン番号

増加しています

1 at

変わる

ハッシュ

デフォルト:0







2







create_txtime







時間

作成中







2016-12-11 10:16:10







update_txtime







時間

最後の

更新

バージョン

(増加

ver_id)







2016-12-11 11:23:14











1 => array ( 'verId' => 2, 'hash' => '0539f31fee4efd845a24c9878cd721b2', 'fnFullName' => 'core.location_save@master' )
      
      









 $this->db->exec( "select core.location_save%ver%(...)" );
      
      







ストアドプロシージャの展開は、辞書のアセンブリの前に、プロジェクトアセンブリの最初のステップで実行されます。



プロジェクトの各ストアドプロシージャファイルについて:



  1. ファイルの内容からハッシュ合計が計算され、ストアドプロシージャの最小バージョンがstored_proceduresテーブルの新しいハッシュ合計で検索されます。
  2. 何も見つからなかった場合(以前はこのようなプロシージャはどのブランチにもデプロイされていませんでした)、新しいプロシージャのバージョンがインクリメントされ、データベースへのこのプロシージャのデプロイが許可されます。
  3. この新しいハッシュを使用するストアドプロシージャが他のブランチで既に使用されている場合、現在のブランチは、データベースへの新しいデプロイメントなしで、このプロシージャを最小バージョンでも使用します。
  4. このブランチでこのストアドプロシージャが以前に使用され、新しいハッシュが現在のレコードのstored_proceduresテーブルのハッシュと異なり、新しいハッシュを含むこのストアドプロシージャが...

    -他のブランチで使用されておらず、最小バージョンが不明な場合、新しい手順ではバージョンが増加し、データベースへの展開が許可されます。

    -他のブランチで使用されていて、最小バージョンがわかっている場合、現在のブランチは、データベースへの新しいコード展開なしで、最小バージョンの既存のストアドプロシージャを使用します。
  5. stored_proceduresテーブルへの初期登録またはver_id更新の場合、ストアドプロシージャを作成するためのコードは、ストアドプロシージャを作成するためのSQLヘッダーに事前に準備されたバージョンを使用してターゲットベースで実行されます。



     CREATE OR REPLACE FUNCTION core.location_save(...)
          
          





    PHPではになります



     CREATE OR REPLACE FUNCTION core.location_save_ver2(...)
          
          





    ベースで実行します。



    core.location_save.sqlファイルは変更されません。

  6. 次に、ディクショナリがアセンブルされます。このステージには、このブランチのストアドプロシージャの現在のバージョンが含まれています。






このバージョン管理コードの利点:









短所:





2番目のバージョン管理オプション



あなたが推測した次のオプションは、前のオプションのマイナスから来ました。 新しいプロジェクトアセンブリごとに一意のスキームとユーザーを作成することによりバージョン管理として指定します。







詳細



すべてのアセンブリに関する情報は、メインサーバー上のデータベースのbuild_historyテーブルに格納されます。

列名







説明













build_branch







収集するブランチの名前







deploy_search_path







build_tag







プロジェクトの将来のアーカイブの名前







デプロイ_1501247988







build_time







プロジェクトのビルド時間







17/28/17 1:19:48午後







schema_name







プロジェクトの指定スキーム







z_build_1







schema_user







プロジェクトの指定データベースユーザー







user_1







deploy_time







新しいプロジェクトコードに切り替える時間







07/28/17 14:05:22











プロジェクトの組み立て中の戦闘展開のプロセス:



  1. アセンブリが起動されると、新しいアセンブリに関する情報がbuild_historyテーブルに記録され、データベースサーバーに接続するための一意のスキームとユーザーが割り当てられます。
  2. ユーザーは、プロジェクトコードと共に展開される構成に書き込みます。
  3. デプロイメント用の特別なユーザーの下にデータベースサーバーへの接続があります
  4. データベースでは、ストアドプロシージャが割り当てられたスキーマが作成されます(存在する場合は再作成されます)。
  5. プロジェクトコードがすべてのアプリケーションサーバーに配置された後、シンボリックリンクが新しいプロジェクトコードに置き換えられると、これらのサーバーのいずれかがメインサーバーにアクセスします。

    -build_historyテーブルで新しいプロジェクトコードに切り替える時間を設定します。

    - プロダクショングループは選択したユーザーに割り当てられ、誰が戦闘に参加しているかを知るために、さらにシンボリックリンクを切り替えずにプロジェクトを繰り返し再構築する場合に、ストアドプロシージャでスキームを誤ってやり過ぎないようにします。

    -スキームが作成されたすべてのサーバーでフォームの新しいsearch_pathが設定されます。

    search_path = public、<assigned schema>の場合:

    -専用ユーザーuser_N;

    -DBA開発者およびチーム。

    -さまざまなクラウンなどのユーザー


pgbouncerでプールを設定するための重要な追加



pgbouncerを使用する場合、プールのサイズを制限するには、 pool_sizeと等しいmax_db_connectionsオプションを使用する必要があります。 これがない場合、各プールユーザーは独自のpool_sizeを持ちます。 この動作は文書化されていませんが、max_db_connectionsは次のように機能します。プール内のすべてのユーザーのアクティブなトランザクションの数を制限します。







pgbouncerプールの例:











 my_database = host=localhost pool_size=5 max_db_connections=5
      
      





結論として、提示されたコードバージョン管理のバージョンは、24時間365日の高負荷モードで優れた結果を示し、ハイブリッドモードで使用されていることに注意してください。 しかし最近、search_pathの2番目のメソッドをより優先します。







ご清聴ありがとうございました!








All Articles