CIミラーテーブル
問題ステートメント
GitLabが使用している単一のデータベースを、main
とci
の2つのデータベースに分割することを目的としたデータベース分割作業の一環として、 main
とci
テーブルの間のすべての結合を削除するという大きな課題が発生しました。PostgreSQLは異なるデータベースに属するテーブル間の結合をサポートしていないからです。しかし、メインデータベースにあるいくつかのコアアプリケーションモデルは、CIサイドから非常に頻繁にクエリされます。例えば
-
Namespace
namespaces
。 -
Project
projects
。
これらのテーブルでjoins
。チームは、メイン・データベースからCIデータベースへ、これらのテーブルを新しいテーブルに論理レプリケーションすることを選択しました:
-
ci_namespace_mirrors
namespaces
テーブルのミラーとして -
ci_project_mirrors
projects
テーブルのミラーとして
この論理レプリケーションには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::CiNamespaceMirrorsConsistencyCheckWorker
Database::CiProjectMirrorsConsistencyCheckWorker
これらのジョブは
- カーソルを使用して、
main
データベース上の両方のソース・テーブルをスキャンします。 -
namespaces
およびprojects
の項目をci
データベースのターゲット・テーブルと比較します。 - 同期していない項目を Kibana と Prometheus にレポーターします。
- 不一致を修正します。