CIミラーテーブル
問題ステートメント
GitLabが使用している単一のデータベースを、main とci の2つのデータベースに分割することを目的としたデータベース分割作業の一環として、 main とci テーブルの間のすべての結合を削除するという大きな課題が発生しました。PostgreSQLは異なるデータベースに属するテーブル間の結合をサポートしていないからです。しかし、メインデータベースにあるいくつかのコアアプリケーションモデルは、CIサイドから非常に頻繁にクエリされます。例えば
-
Namespacenamespaces。 -
Projectprojects。
これらのテーブルでjoins 。チームは、メイン・データベースからCIデータベースへ、これらのテーブルを新しいテーブルに論理レプリケーションすることを選択しました:
-
ci_namespace_mirrorsnamespacesテーブルのミラーとして -
ci_project_mirrorsprojectsテーブルのミラーとして
この論理レプリケーションには2つの意味があります:
-
mainデータベースのテーブルをクエリし、namespacesおよびprojectsテーブルに結合できます。 -
ciデータベース・テーブルは、ci_namespace_mirrorsおよびci_project_mirrorsテーブルと結合できます。
このレプリケーションは、それぞれのモデルから必要とされるいくつかの属性のみに制限されています:
-
Namespaceから、traversal_idsを複製します。 -
Projectからは、プロジェクトが属するグループを表すnamespace_idのみを複製します。
CIでミラーリングされたテーブルをソーステーブルと同期させる方法
ソース・テーブルとターゲット・テーブルを同期させるためには、2つのタイプ3のイベントに注意する必要があります:
- 新しいネームスペースまたはプロジェクトの作成。
- ネームスペースまたはプロジェクトの更新。
- ネームスペース/プロジェクトの削除。
作成と更新
新しく作成または更新されたネームスペースまたはプロジェクトのデータの同期は、この順序で行われます:
- **
mainデータベース** :namespacesまたはprojectsテーブル上のINSERTまたはUPDATEは、テーブルnamespaces_sync_eventsおよびprojects_sync_eventsにエントリを追加します。これらのテーブルはmainデータベースにも存在します。これらのエントリは、両方のテーブルのトリガによって追加されます。 -
モデルレベルではソース・モデル
NamespaceまたはProjectのいずれかでコミットが発生すると、対応するSidekiqジョブNamespaces::ProcessSyncEventsWorkerまたはProjects::ProcessSyncEventsWorkerの実行がスケジュールされます。 - これらのワーカーは次に
-
mainデータベースから(namespaces/project)_sync_eventsテーブルのエントリを読み込んで、同期するネームスペースやプロジェクトをチェックします。 - 更新されたレコードのデータをターゲット・テーブル
ci_namespace_mirrors,ci_project_mirrorsにコピーします。
-
削除
namespaces またはprojects のいずれかが削除されると、緩い外部キー (LFK) メカニズムを使用して、ミラーリングされた CI テーブルの対象レコードが削除されます。
config/gitlab_loose_foreign_keys.yml にこれらの項目があることで、LFK メカニズムはすでに期待通りに動作していました。これは、main データベースで削除されたnamespaces またはprojects にマッピングされた CI ミラーテーブル上のレコードを削除します。
ci_namespace_mirrors:
- table: namespaces
column: namespace_id
on_delete: async_delete
ci_project_mirrors:
- table: projects
column: project_id
on_delete: async_delete
整合性チェック
両方の同期メカニズムが期待通りに動作することを確認するために、数分ごとに cron ジョブによって起動される 2 つの特別なワーカージョブをデプロイします:
Database::CiNamespaceMirrorsConsistencyCheckWorkerDatabase::CiProjectMirrorsConsistencyCheckWorker
これらのジョブは
- カーソルを使用して、
mainデータベース上の両方のソース・テーブルをスキャンします。 -
namespacesおよびprojectsの項目をciデータベースのターゲット・テーブルと比較します。 - 同期していない項目を Kibana と Prometheus にレポーターします。
- 不一致を修正します。