トラブルシューティング Geo

Geo のセットアップには細部まで注意を払う必要があり、時には手順を見落としがちです。

以下は、問題を解決するために取るべき手順のリストです:

  1. 基本的なトラブルシューティングを行います。
  2. PostgreSQLデータベースのレプリケーションエラーを修正します。
  3. 一般的なエラーを修正します。
  4. PostgreSQL以外のレプリケーションの失敗を修正します。

基本的なトラブルシューティング

より高度なトラブルシューティングを行う前に

Geo サイトの健全性の確認

プライマリサイトで

  1. 左のサイドバーで、Search を選択するか、次のページに進んでください。
  2. Admin Areaを選択します。
  3. 左サイドバーでGeo > Sites を選択します。

各セカンダリー・サイトで以下のヘルス・チェックを行い、何か問題があるかどうかを特定します:

  • サイトは稼動していますか?
  • セカンダリ・サイトのデータベースはストリーミング・レプリケーション用に設定されていますか?
  • セカンダリ・サイトの追跡データベースは設定されていますか?
  • セカンダリサイトのトラッキングデータベースは接続されていますか?
  • セカンダリサイトのトラッキングデータベースは最新ですか?
  • セカンダリサイトのステータスは10分以内ですか?

Geo health check

サイトのステータスが10分以上経過している場合、サイトは「Unhealthy」と表示されます。その場合は、影響を受けるセカンダリサイトのRailsコンソールで以下を実行してみてください:

Geo::MetricsUpdateWorker.new.perform

エラーが発生する場合は、そのエラーがジョブの完了を妨げている可能性もあります。10分以上かかる場合はパフォーマンスに問題があり、最終的にステータスが更新されてもUIが常に「Unhealthy」と表示される可能性があります。

ステータスの更新に成功した場合、Sidekiqに何か問題がある可能性があります。動作していますか?ログはエラーを表示していますか?このジョブは1分ごとにエンキューされることになっており、ジョブ重複排除idempotencyキーが適切にクリアされなかった場合、実行されない可能性があります。Redisでは排他的リースを取り、一度に1つのジョブしか実行できないようにしています。プライマリサイトはPostgreSQLデータベースで直接ステータスを更新します。セカンダリサイトはHTTP Postリクエストをプライマリサイトに送り、ステータスデータを渡します。

特定の健全性チェックが失敗した場合、サイトは “Unhealthy “と表示されます。影響を受けるセカンダリサイトのRailsコンソールで以下を実行することで、失敗を明らかにすることができます:

Gitlab::Geo::HealthCheck.new.perform_checks

"" (空の文字列)または"Healthy"を返したら、チェックは成功です。それ以外が返された場合は、何が失敗したかをメッセージで説明するか、例外メッセージを表示する必要があります。

ユーザー・インターフェースからレポーターされる一般的なエラー・メッセージの解決方法については、「一般的なエラーの修正」を参照してください。

ユーザー インターフェイスが機能していない場合、またはサインインできない場合は、手動で Geo 健全性チェックを実行して、これらの情報ともう少し詳しい情報を得ることができます。

健全性チェック Rake タスク

カスタムNTPサーバーの使用はGitLab 15.7で導入されました。

このRakeタスクはプライマリサイトまたはセカンダリサイトの Railsノードで実行できます:

sudo gitlab-rake gitlab:geo:check

出力例です:

Checking Geo ...

GitLab Geo is available ... yes
GitLab Geo is enabled ... yes
This machine's Geo node name matches a database record ... yes, found a secondary node named "Shanghai"
GitLab Geo tracking database is correctly configured ... yes
Database replication enabled? ... yes
Database replication working? ... yes
GitLab Geo HTTP(S) connectivity ...
* Can connect to the primary node ... yes
HTTP/HTTPS repository cloning is enabled ... yes
Machine clock is synchronized ... yes
Git user has default SSH configuration? ... yes
OpenSSH configured to use AuthorizedKeysCommand ... yes
GitLab configured to disable writing to authorized_keys file ... yes
GitLab configured to store new projects in hashed storage? ... yes
All projects are in hashed storage? ... yes

Checking Geo ... Finished

環境変数を使ってカスタムNTPサーバを指定することもできます。例えば

sudo gitlab-rake gitlab:geo:check NTP_HOST="ntp.ubuntu.com" NTP_TIMEOUT="30"

以下の環境変数がサポートされています。

変数説明デフォルト値
NTP_HOSTNTPホスト。pool.ntp.org
NTP_PORTホストがリッスンする NTP ポート。ntp
NTP_TIMEOUTNTP タイムアウト (秒)。 net-ntp Ruby ライブラリで定義されている値(60 秒)。

RakeタスクがOpenSSH configured to use AuthorizedKeysCommand チェックをスキップした場合、以下の出力が表示されます:

OpenSSH configured to use AuthorizedKeysCommand ... skipped
  Reason:
  Cannot access OpenSSH configuration file
  Try fixing it:
  This is expected if you are using SELinux. You may want to check configuration manually
  For more information see:
  doc/administration/operations/fast_ssh_key_lookup.md

このイシューは以下の場合に発生する可能性があります:

  • SELinuxを使用している場合。
  • SELinux を使っておらず、git ユーザーが OpenSSH 設定ファイルにアクセスできないのは、ファイルの権限が制限されているからです。

後者の場合、次の出力は、root ユーザーだけがこのファイルを読めることを示しています:

sudo stat -c '%G:%U %A %a %n' /etc/ssh/sshd_config

root:root -rw------- 600 /etc/ssh/sshd_config

ファイルのオーナーや権限を変更せずに、git ユーザーが OpenSSH 設定ファイルを読めるようにするには、acl

sudo setfacl -m u:git:r /etc/ssh/sshd_config

同期ステータス Rakeタスク

現在の同期情報は、GeoセカンダリサイトでRails(Puma、Sidekiq、Geo Log Cursor)を実行しているノードでこのRakeタスクを実行することで手動で確認できます。

GitLabはオブジェクトストレージに保存されているオブジェクトを検証しません。オブジェクトストレージを使用している場合、すべての “verified “チェックで成功が0と表示されます。これは予想されることであり、心配することではありません。

sudo gitlab-rake geo:status

出力には以下のようなものがあります:

  • 失敗があった場合の「失敗した」項目の数
  • 成功」した項目の「合計」に対する割合。

使用例:

http://secondary.example.com/
-----------------------------------------------------
                        GitLab Version: 14.9.2-ee
                              Geo Role: Secondary
                         Health Status: Healthy
                          Repositories: succeeded 12345 / total 12345 (100%)
                 Verified Repositories: succeeded 12345 / total 12345 (100%)
                                 Wikis: succeeded 6789 / total 6789 (100%)
                        Verified Wikis: succeeded 6789 / total 6789 (100%)
                           Attachments: succeeded 4 / total 4 (100%)
                      CI job artifacts: succeeded 0 / total 0 (0%)
                   Design repositories: succeeded 1 / total 1 (100%)
                           LFS Objects: failed 1 / succeeded 2 / total 3 (67%)
                   Merge Request Diffs: succeeded 0 / total 0 (0%)
                         Package Files: failed 1 / succeeded 2 / total 3 (67%)
              Terraform State Versions: failed 1 / succeeded 2 / total 3 (67%)
                  Snippet Repositories: failed 1 / succeeded 2 / total 3 (67%)
               Group Wiki Repositories: succeeded 4 / total 4 (100%)
                    Pipeline Artifacts: failed 3 / succeeded 0 / total 3 (0%)
                     Pages Deployments: succeeded 0 / total 0 (0%)
                  Repositories Checked: failed 5 / succeeded 0 / total 5 (0%)
                Package Files Verified: succeeded 0 / total 10 (0%)
     Terraform State Versions Verified: succeeded 0 / total 10 (0%)
         Snippet Repositories Verified: succeeded 99 / total 100 (99%)
           Pipeline Artifacts Verified: succeeded 0 / total 10 (0%)
                         Sync Settings: Full
              Database replication lag: 0 seconds
       Last event ID seen from primary: 12345 (about 2 minutes ago)
               Last event ID processed: 12345 (about 2 minutes ago)
                Last status report was: 1 minute ago

各項目には最大3つのステータスがあります。例えば、Repositories の場合、以下の行が表示されます:

  Repositories: succeeded 12345 / total 12345 (100%)
  Verified Repositories: succeeded 12345 / total 12345 (100%)
  Repositories Checked: failed 5 / succeeded 0 / total 5 (0%)

3つのステータス項目は以下のように定義されています:

  • Repositories 出力は、プライマリからセカンダリに同期されたリポジトリの数を示します。
  • Verified Repositories 出力は、セカンダリ上のリポジトリチェックサムがプライマリと一致するリポジトリの数を示しています。
  • Repositories Checked は、セカンダリ上で Git リポジトリの内部チェック (git fsck) を通過したリポジトリの数を表します。

失敗した項目の詳細については、 gitlab-rails/geo.log ファイルを参照ください。

レプリケーションや検証に失敗した場合は、それを解決することができます。

リポジトリのチェックに失敗した場合は、その解決を試みることができます。

Geo check Rake タスクの実行時に見つかったエラーの修正

このRakeタスクを実行する際、ノードが適切に設定されていないとエラーメッセージが表示されることがあります:

sudo gitlab-rake gitlab:geo:check
  • Railsがデータベースに接続する際にパスワードを提供しませんでした。

     Checking Geo ...
       
     GitLab Geo is available ... Exception: fe_sendauth: no password supplied
     GitLab Geo is enabled ... Exception: fe_sendauth: no password supplied
     ...
     Checking Geo ... Finished
    

    postgresql['sql_user_password'] のハッシュを作成するときに使用したプレーンテキストのパスワードをgitlab_rails['db_password'] に設定していることを確認してください。

  • Railsがデータベースに接続できません。

     Checking Geo ...
       
     GitLab Geo is available ... Exception: FATAL:  no pg_hba.conf entry for host "1.1.1.1",  user "gitlab", database "gitlabhq_production", SSL on
     FATAL:  no pg_hba.conf entry for host "1.1.1.1", user "gitlab", database "gitlabhq_production", SSL off
     GitLab Geo is enabled ... Exception: FATAL:  no pg_hba.conf entry for host "1.1.1.1", user "gitlab", database "gitlabhq_production", SSL on
     FATAL:  no pg_hba.conf entry for host "1.1.1.1", user "gitlab", database "gitlabhq_production", SSL off
     ...
     Checking Geo ... Finished
    

    Rails ノードの IP アドレスがpostgresql['md5_auth_cidr_addresses'] に含まれていることを確認してください。また、IPアドレスにサブネットマスクが含まれていることを確認してください:postgresql['md5_auth_cidr_addresses'] = ['1.1.1.1/32']

  • Railsのパスワードが正しくありません。

     Checking Geo ...
     GitLab Geo is available ... Exception: FATAL:  password authentication failed for user "gitlab"
     FATAL:  password authentication failed for user "gitlab"
     GitLab Geo is enabled ... Exception: FATAL:  password authentication failed for user "gitlab"
     FATAL:  password authentication failed for user "gitlab"
     ...
     Checking Geo ... Finished
    

    gitlab-ctl pg-password-md5 gitlab を実行してパスワードを入力し、postgresql['sql_user_password'] でハッシュを作成するときに使用した正しいパスワードがgitlab_rails['db_password'] に設定されていることを確認してください。

  • not a secondary node が戻ってくることを確認してください。

     Checking Geo ...
       
     GitLab Geo is available ... yes
     GitLab Geo is enabled ... yes
     GitLab Geo tracking database is correctly configured ... not a secondary node
     Database replication enabled? ... not a secondary node
     ...
     Checking Geo ... Finished
    

    プライマリ・サイトのウェブ・インターフェイスのGeo > Sitesにある管理エリアにセカンダリ・サイトを追加していることを確認してください。また、プライマリサイトのアドミンエリアでセカンダリサイトを追加する際にgitlab_rails['geo_node_name'] を入力したことを確認してください。GitLab 12.3 以前では、プライマリサイトのアドミンエリアでセカンダリサイトを編集し、Name フィールドの末尾に/ があることを確認してください。

  • Exception: PG::UndefinedTable: ERROR: relation "geo_nodes" does not exist が戻ってくることを確認してください。

     Checking Geo ...
       
     GitLab Geo is available ... no
       Try fixing it:
       Add a new license that includes the GitLab Geo feature
       For more information see:
       https://about.gitlab.com/features/gitlab-geo/
     GitLab Geo is enabled ... Exception: PG::UndefinedTable: ERROR:  relation "geo_nodes" does not exist
     LINE 8:                WHERE a.attrelid = '"geo_nodes"'::regclass
                                                ^
     :               SELECT a.attname, format_type(a.atttypid, a.atttypmod),
                          pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
                          c.collname, col_description(a.attrelid, a.attnum) AS comment
                     FROM pg_attribute a
                     LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
                     LEFT JOIN pg_type t ON a.atttypid = t.oid
                     LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
                    WHERE a.attrelid = '"geo_nodes"'::regclass
                      AND a.attnum > 0 AND NOT a.attisdropped
                    ORDER BY a.attnum
     ...
     Checking Geo ... Finished
    

    PostgreSQLのメジャーバージョン(9 > 10)を実行する場合、この更新が期待されます。initiate-the-replication-processに従ってください。

  • RailsにGeoトラッキングデータベースへの接続に必要な設定がないようです。

     Checking Geo ...
       
     GitLab Geo is available ... yes
     GitLab Geo is enabled ... yes
     GitLab Geo tracking database is correctly configured ... no
     Try fixing it:
     Rails does not appear to have the configuration necessary to connect to the Geo tracking database. If the tracking database is running on a node other than this one, then you may need to add configuration.
     ...
     Checking Geo ... Finished
    
メッセージマシンクロックは同期されています …例外

Rake タスクは、サーバーの時計が NTP と同期していることを確認しようとします。Geo が正しく機能するためには、クロックの同期が必要です。例として、セキュリティのため、プライマリサイトとセカンダリサイトのサーバー時刻が約 1 分以上異なる場合、Geo サイト間のリクエストは失敗します。時刻の不一致以外の理由でこのチェックタスクが完了しなかった場合でも、必ずしも Geo が機能しないわけではありません。

このチェックを行う Ruby gem は、pool.ntp.org を参照時間ソースとしてハードコーディングされています。

  • 例外メッセージMachine clock is synchronized ... Exception: Timeout::Error

    このイシューは、サーバーがホストpool.ntp.org にアクセスできない場合に発生します。

  • 例外メッセージMachine clock is synchronized ... Exception: No route to host - recvfrom(2)

    このイシューは、ホスト名pool.ntp.org がタイムサービスを提供していないサーバーに解決される場合に発生します。

この場合、GitLab 15.7以降では環境変数を使ってカスタムNTPサーバーを指定してください。

GitLab 15.6以前では、以下の回避策のいずれかを使用してください:

  • /etc/hosts forpool.ntp.org にエントリを追加して、リクエストを有効な内部タイムサーバーに向けるようにします。これにより、長いタイムアウトとタイムアウトエラーが修正されます。
  • チェックを有効なIPアドレスに向けます。これにより、タイムアウトのイシューは解決されますが、上述のように、No route to host エラーでチェックが失敗します。

Kubernetesのコンテナはホストクロックにアクセスできないため、クラウドネイティブのGitLabデプロイはエラーを生成します:

Machine clock is synchronized ... Exception: getaddrinfo: Servname not supported for ai_socktype
メッセージActiveRecord::StatementInvalid: PG::ReadOnlySqlTransaction: ERROR: cannot execute INSERT in a read-only transaction

このエラーがセカンダリサイトで発生した場合、GitLab Railsのgitlab-railsgitlab-rake コマンド、Puma、Sidekiq、Geo Log Cursorサービスなど、GitLab Railsのすべての使用に影響が及ぶ可能性があります。

ActiveRecord::StatementInvalid: PG::ReadOnlySqlTransaction: ERROR:  cannot execute INSERT in a read-only transaction
/opt/gitlab/embedded/service/gitlab-rails/app/models/application_record.rb:86:in `block in safe_find_or_create_by'
/opt/gitlab/embedded/service/gitlab-rails/app/models/concerns/cross_database_modification.rb:92:in `block in transaction'
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/database.rb:332:in `block in transaction'
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/database.rb:331:in `transaction'
/opt/gitlab/embedded/service/gitlab-rails/app/models/concerns/cross_database_modification.rb:83:in `transaction'
/opt/gitlab/embedded/service/gitlab-rails/app/models/application_record.rb:86:in `safe_find_or_create_by'
/opt/gitlab/embedded/service/gitlab-rails/app/models/shard.rb:21:in `by_name'
/opt/gitlab/embedded/service/gitlab-rails/app/models/shard.rb:17:in `block in populate!'
/opt/gitlab/embedded/service/gitlab-rails/app/models/shard.rb:17:in `map'
/opt/gitlab/embedded/service/gitlab-rails/app/models/shard.rb:17:in `populate!'
/opt/gitlab/embedded/service/gitlab-rails/config/initializers/fill_shards.rb:9:in `<top (required)>'
/opt/gitlab/embedded/service/gitlab-rails/config/environment.rb:7:in `<top (required)>'
/opt/gitlab/embedded/bin/bundle:23:in `load'
/opt/gitlab/embedded/bin/bundle:23:in `<main>'

PostgreSQLのread-replicaデータベースがこのエラーを発生させているのでしょう:

2023-01-17_17:44:54.64268 ERROR:  cannot execute INSERT in a read-only transaction
2023-01-17_17:44:54.64271 STATEMENT:  /*application:web,db_config_name:main*/ INSERT INTO "shards" ("name") VALUES ('storage1') RETURNING "id"

この状況は、セカンダリ・サイトがまだセカンダリ・サイトであることを認識していない初期設定中に発生する可能性があります。

エラーを解決するには、手順3.セカンダリ・サイトを追加します。

PostgreSQLのレプリケーションが機能しているか確認します。

PostgreSQLのレプリケーションが動作しているかどうかを確認するには、次のようにします:

サイトは正しいデータベースノードを指していますか?

プライマリGeoサイトが書き込み権限のあるデータベースノードを指していることを確認する必要があります。

セカンダリノードは読み取り専用のデータベースノードのみを指すようにしてください。

Geo は現在のサイトを正しく検出できますか?

Geoは/etc/gitlab/gitlab.rb 、以下のロジックで現在のPumaまたはSidekiqノードのGeoサイト名を検出します:

  1. Geo node name “を取得します(設定を “Geo site name “にリネームするイシューがあります):
    • Linux パッケージ:gitlab_rails['geo_node_name'] 設定を取得します。
    • GitLab Helmチャート:global.geo.nodeName の設定を取得します(GitLab Geoを使ったチャートを参照)。
  2. それが定義されていない場合は、external_url の設定を取得してください。

この名前はGeo Sitesダッシュボードで同じ名前のGeo サイトを検索するために使用されます。

現在のマシンにデータベース内のサイトと一致するサイト名があるかどうかを確認するには、チェック タスクを実行します:

sudo gitlab-rake gitlab:geo:check

現在のマシンのサイト名と、一致するデータベースレコードがプライマリサイトか セカンダリサイトかが表示されます。

This machine's Geo node name matches a database record ... yes, found a secondary node named "Shanghai"
This machine's Geo node name matches a database record ... no
  Try fixing it:
  You could add or update a Geo node database record, setting the name to "https://example.com/".
  Or you could set this machine's Geo node name to match the name of an existing database record: "London", "Shanghai"
  For more information see:
  doc/administration/geo/replication/troubleshooting.md#can-geo-detect-the-current-node-correctly

Name フィールドの説明にある推奨サイト名の詳細については、Geo Admin Area Common Settings を参照してください。

OS ロケールデータの互換性チェック

異なるオペレーティングシステムや異なるオペレーティングシステムのバージョンが Geo サイト間でデプロイされている場合、Geo をセットアップする前にロケールデータの互換性チェックを行う必要があります。

Geo は PostgreSQL と Streaming Replication を使って Geo サイト間でデータを複製します。PostgreSQL は、オペレーティングシステムの C ライブラリによって提供されるロケール データをテキストの並べ替えに使用します。C ライブラリのロケールデータが Geo サイト間で互換性がない場合、セカンダリサイトで正しくない動作につながる誤ったクエリ結果を引き起こす可能性があります。

例えば、Ubuntu 18.04 (およびそれ以前) と RHEL/Centos7 (およびそれ以前) は、それ以降のリリースと互換性がありません。詳細はPostgreSQLのWikiを参照してください。

すべてのGeoサイトでPostgreSQLを実行しているすべてのホストで、以下のShellコマンドを実行してください:

( echo "1-1"; echo "11" ) | LC_COLLATE=en_US.UTF-8 sort

出力は以下のようになります:

1-1
11

またはその逆:

11
1-1

出力がすべてのホストで同じであれば、互換性のあるバージョンのロケールデータを実行していることになります。

一部のホストで出力が異なる場合、PostgreSQLのレプリケーションが正しく動作していません。互換性のあるオペレーティングシステムのバージョンを選択してください。

ディスク上のデータが互換性のないロケールのオペレーティングシステムに “静止状態で “転送された場合や、レプリケーションによって転送された場合は、インデックスの完全な再構築が必要です。

このチェックは、GitLabのデプロイを混在して使う場合にも必要です。Linux パッケージインストール、GitLab Docker コンテナ、Helm チャートデプロイ、外部データベースサービスなどでロケールが異なる場合があります。

PostgreSQL データベースのレプリケーションエラーの修正

メッセージ:WARNING: oldest xmin is far in the pastpg_wal のサイズが大きくなっています。

レプリケーションスロットが非アクティブの場合、そのスロットに対応するpg_wal のログは永久に(もしくはスロットが再びアクティブになるまで)予約されます。これによりディスク使用量が増加し続け、PostgreSQLログに以下のメッセージが繰り返し表示されます:

WARNING: oldest xmin is far in the past
HINT: Close open transactions soon to avoid wraparound problems.
You might also need to commit or roll back old prepared transactions, or drop stale replication slots.

この問題を解決するには

  1. プライマリデータベースに接続します。

  2. SELECT * FROM pg_replication_slots; を実行します。activef (偽)としてレポーターするslot_name に注意してください。

  3. そのGeoサイトを削除する手順に従ってください。

以下のセクションでは、レプリケーション エラー メッセージ(geo:check の出力Database replication working? ... no で示されている)を修正するためのトラブルシューティング手順の概要を説明します。

メッセージが表示されます:ERROR: replication slots can only be used if max_replication_slots > 0?

これは、max_replication_slots PostgreSQL変数をプライマリデータベースに設定する必要があることを意味します。セカンダリサイトの数が多い場合は、この値を増やす必要があるかもしれません。

この設定を有効にするには、必ずPostgreSQLを再起動してください。詳細はPostgreSQLレプリケーション設定ガイドを参照してください。

メッセージが表示されます:FATAL: could not start WAL streaming: ERROR: replication slot "geo_secondary_my_domain_com" does not exist?

PostgreSQLにその名前のセカンダリサイト用のレプリケーションスロットがない場合に発生します。

セカンダリサイトの レプリケーションプロセスを再実行してください。

メッセージ「レプリケーション設定時に「コマンドが実行可能時間を超えました。

これは、セカンダリサイトで レプリケーションプロセスを開始する際に発生する可能性があり、初期データセットがデフォルトのタイムアウト(30分)ではレプリケートできないほど大きすぎることを示しています。

gitlab-ctl replicate-geo-database を再実行してください。ただし、--backup-timeout の値を大きくしてください:

sudo gitlab-ctl \
   replicate-geo-database \
   --host=<primary_node_hostname> \
   --slot-name=<secondary_slot_name> \
   --backup-timeout=21600

これにより、初期レプリケーションが完了するまで、デフォルトの30分ではなく、最大6時間になります。インストールに応じて調整してください。

メッセージ”PANIC: ファイルに書き込めませんでしたpg_xlog/xlogtemp.123: デバイスに空き容量がありません”

プライマリ・データベースに未使用のレプリケーション・スロットがあるかどうかを確認してください。これは、pg_xlog. pg_xlogNET データベースに大量のログ・データが蓄積される原因になります。pg_xlog未使用のスロットを削除すると、.NET データベースで使用される pg_xlog容量を減らすことができます。

  1. PostgreSQLコンソール・セッションを開始します:

    sudo gitlab-psql
    
    note
    レプリケーション・スロットの管理にはスーパーユーザ権限が必要なため、gitlab-rails dbconsole
  2. レプリケーション・スロットを表示します:

    SELECT * FROM pg_replication_slots;
    

activef のスロットはアクティビティではありません。

  • セカンダリサイトがそのスロットを使用して設定されているため、このスロットがアクティブであるべき場合、セカンダリサイトのWebインタフェースにサインインし、PostgreSQLのログを確認して、レプリケーションが実行されていない理由を確認してください。

  • そのスロットをもう使用しない場合(例えば、Geoを有効にしていない場合)、PostgreSQLコンソールセッションでそのスロットを削除することができます:

     SELECT pg_drop_replication_slot('<name_of_extra_slot>');
    

メッセージ”ERROR: リカバリとの競合により文をキャンセルします”

このエラーメッセージは一般的な使用法では頻繁に発生するものではなく、システムは回復するのに十分な回復力を持っています。

しかし、特定の条件下では、セカンダリ上のデータベース・クエリが過度に長く実行されることがあり、このエラー・メッセージの発生頻度が高くなります。このため、レプリケーションのたびにクエリがキャンセルされ、一部のクエリが完了しないという状況が発生する可能性があります。

これらの長時間実行クエリは将来的に削除される予定ですが、回避策として、hot_standby_feedback を有効にすることをお勧めします。これは、VACUUM 、最近死んだ行の削除を防ぐため、プライマリ・サイトで肥大化する可能性が高くなります。しかし、GitLab.com の本番環境ではこの方法で成功しています。

hot_standby_feedback を有効にするには、セカンダリサイトの /etc/gitlab/gitlab.rb に以下を追加します:

postgresql['hot_standby_feedback'] = 'on'

それからGitLabを再設定してください:

sudo gitlab-ctl reconfigure

この問題を解決するには、イシューにコメントしてください。

メッセージFATAL: could not connect to the primary server: server certificate for "PostgreSQL" does not match host name

これは、Linuxパッケージが自動的に作成するPostgreSQL証明書にCommon NamePostgreSQL が含まれているために起こりますが、レプリケーションは別のホストに接続しており、GitLabはデフォルトでverify-full SSLモードを使用しようとします。

このイシューを解決するには、以下のどちらかを行います:

  • replicate-geo-database コマンドで--sslmode=verify-ca 引数を使用します。
  • すでに複製されているデータベースの場合は、/var/opt/gitlab/postgresql/data/gitlab-geo.confsslmode=verify-fullsslmode=verify-ca に変更し、gitlab-ctl restart postgresqlを実行します。
  • 自動生成された証明書を使用する代わりに、カスタム証明書(CNまたはSANにデータベースへの接続に使用するホスト名を含む)を使用してPostgreSQL用のSSLを設定します。

メッセージLOG: invalid CIDR mask in address

この現象はpostgresql['md5_auth_cidr_addresses'] のアドレスの書式が間違っている場合に起こります。

2020-03-20_23:59:57.60499 LOG:  invalid CIDR mask in address "***"
2020-03-20_23:59:57.60501 CONTEXT:  line 74 of configuration file "/var/opt/gitlab/postgresql/data/pg_hba.conf"

これを修正するには、postgresql['md5_auth_cidr_addresses'] の下にある/etc/gitlab/gitlab.rb の IP アドレスを更新して、CIDR フォーマット (例えば、10.0.0.1/32) を尊重するようにしてください。

メッセージLOG: invalid IP mask "md5": Name or service not known

この問題は、postgresql['md5_auth_cidr_addresses'] でサブネットマスクを指定せずに IP アドレスを追加した場合に発生します。

2020-03-21_00:23:01.97353 LOG:  invalid IP mask "md5": Name or service not known
2020-03-21_00:23:01.97354 CONTEXT:  line 75 of configuration file "/var/opt/gitlab/postgresql/data/pg_hba.conf"

これを解決するには、postgresql['md5_auth_cidr_addresses'] の下に、/etc/gitlab/gitlab.rb でサブネットマスクを追加し、CIDR形式を尊重します(例えば、10.0.0.1/32 )。

メッセージ:Found data in the gitlabhq_production database! 実行時gitlab-ctl replicate-geo-database

projects テーブルにデータが検出された場合に発生します。1つ以上のプロジェクトが検出されると、偶発的なデータ損失を防ぐためにオペレーションが中断されます。このメッセージを回避するには、--force オプションをコマンドに渡します。

GitLab 13.4では、GitLabの最初のインストール時にシードプロジェクトが追加されます。このため、新しいGeoセカンダリサイトでも--force 。データベースをチェックする際にシードプロジェクトを考慮するイシューがあります。

同期エラー

すべてのアップロード(または検証されたSSFデータ型)を元に戻します。

  1. プライマリGeoサイトのGitLab RailsノードにSSH接続します。
  2. Railsコンソールを開きます。
  3. すべてのアップロードを “pending verification” としてマークします:
caution
データを変更するコマンドは、正しく実行しなかったり適切な条件下で実行しなかったりすると、ダメージを与える可能性があります。必ず最初にテスト環境でコマンドを実行し、リストアできるようにバックアップインスタンスを用意してください。
Upload.verification_state_table_class.each_batch do |relation|
  relation.update_all(verification_state: 0)
end
  1. これにより、プライマリがすべてのアップロードのチェックサムを開始します。
  2. プライマリがレコードのチェックサムに成功すると、すべてのセカンダリも同様にチェックサムを再計算し、その値を比較します。

Geo Self-Service Frameworkが扱う、検証を実装した他のモデルでも同様のオペレーションを実行できます:

  • LfsObject
  • MergeRequestDiff
  • Packages::PackageFile
  • Terraform::StateVersion
  • SnippetRepository
  • Ci::PipelineArtifact
  • PagesDeployment
  • Upload
  • Ci::JobArtifact
  • Ci::SecureFile
note
GroupWikiRepository は検証が実装されていないため、前のリストにはありません。管理エリアの UI にこの機能を実装するイシューがあります。

メッセージSynchronization failed - Error syncing repository

caution
大規模なリポジトリがこの問題の影響を受ける場合、再同期に時間がかかり、Geo サイト、ストレージ、およびネットワーク システムに大きな負荷がかかる可能性があります。

fatal: fsck error in packed object と共にエラーメッセージSynchronization failed - Error syncing repository が表示された場合、リポジトリの同期時に整合性チェックエラーが発生したことを示しています。

整合性エラーの一例はerror: object f4a87a3be694fbbd6e50a668a31a8513caeaafe3: hasDotgit: contains '.git です。

整合性エラーの原因となる不正なオブジェクトを削除するには、リポジトリの履歴を書き換える必要があります。しかし、一貫性チェックを上書きすることは可能です。そのためには、Gitalyドキュメントの指示に従ってください。

また、以下のログメッセージとともにエラーメッセージSynchronization failed - Error syncing repository が表示されることがあります。これは、セカンダリ Geo サイトのファイルシステム上のリポジトリの.git/config ファイルに、期待されるgeo リモートが存在しないことを示しています:

{
  "created": "@1603481145.084348757",
  "description": "Error received from peer unix:/var/opt/gitlab/gitaly/gitaly.socket",
  
  "grpc_message": "exit status 128",
  "grpc_status": 13
}
{  
  "grpc.request.fullMethod": "/gitaly.RemoteService/FindRemoteRootRef",
  "grpc.request.glProjectPath": "<namespace>/<project>",
  
  "level": "error",
  "msg": "fatal: 'geo' does not appear to be a git repository
          fatal: Could not read from remote repository. …",
}

これを解決するには

  1. セカンダリ Geo サイトのウェブインターフェイスにサインインします。

  2. .git フォルダーをバックアップします。

  3. オプション。これらの ID が本当に Geo レプリケーションの失敗が知られているプロジェクトに対応しているかどうか、いくつかスポットチェックしてください。fatal: 'geo'grep の用語として使用し、以下の API コールを使用します:

    curl --request GET --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/<first_failed_geo_sync_ID>"
    
  4. Railsコンソールに入って実行します:

    failed_geo_syncs = Geo::ProjectRegistry.failed.pluck(:id)
    failed_geo_syncs.each do |fgs|
      puts Geo::ProjectRegistry.failed.find(fgs).project_id
    end
    
  5. 以下のコマンドを実行して、各プロジェクトのGeo関連属性をリセットし、新しい同期を実行します:

    failed_geo_syncs.each do |fgs|
      registry = Geo::ProjectRegistry.failed.find(fgs)
      registry.update(resync_repository: true, force_to_redownload_repository: false, repository_retry_count: 0)
      Geo::RepositorySyncService.new(registry.project).execute
    end
    

バックフィル中の失敗

バックフィル中、失敗はバックフィル・キューの最後で再試行されるようスケジュールされているため、これらの失敗はバックフィルが完了した後にのみ解消されます。

同期失敗のメッセージ:「検証に失敗しました:検証中にエラーが発生しました:ファイルがチェックサム可能ではありません”

Geo プライマリサイトにファイルがありません。

GitLab 14.5以前では、Geoプライマリサイトで欠落している特定のデータタイプが、Geoセカンダリサイトでは “同期済み “とマークされていました。これは、Geo セカンダリサイトから見ると、プライマリサイトと状態が一致しており、セカンダリサイトではそれ以上何もできなかったためです。

セカンダリサイトでは、定期的に「検証」機能を使ってこれらのファイルの同期を試みます:

  • ファイルが存在しないため、検証は失敗します。
  • ファイルは「同期に失敗しました」と表示されます。
  • 同期が再試行されます。
  • ファイルには「同期成功」と表示されます。
  • ファイルには「要検証」と表示されています。
  • プライマリサイトでファイルが再び利用できるようになるまで繰り返します。

レジストリ・エントリはさまざまなバックグラウンド・ジョブによって論理ループの中を移動するため、トラブルシューティングが混乱する可能性があります。また、last_sync_failureverification_failure は、”同期に成功しました” の後、検証が再試行される前に空になります。

同期の失敗が交互に繰り返され、成功が増える一方、成功が減ったり、その逆が繰り返されたりする場合は、プライマリサイトのファイルが見つからないことが原因である可能性があります。セカンダリサイトのgeo.log を検索して、同じファイルに何度も影響を及ぼしているFile is not checksummable を検索することで確認できます。

これが問題であることを確認したら、プライマリ・サイトのファイルを修正する必要があります。考えられる原因

  • NFS共有がアンマウントされました。
  • ディスクが死亡または破損しました。
  • 誰かが意図せずにファイルやディレクトリを削除してしまった場合。
  • GitLab アプリケーションのバグ:
    • 移動されるべきでないファイルが移動されました。
    • あるファイルが移動されるべき時に移動されませんでした。
    • コード内で誤ったパスが生成されました。
  • アトミックでないバックアップがリストアされました。
  • 使用中にサービスまたはサーバ、ネットワークインフラが中断/再起動されました。

適切なアクションは原因によって異なります。たとえば、NFS共有を再マウントすることができます。多くの場合、根本的な原因が明らかでなかったり、発見しても役に立たないことがあります。定期的なバックアップがある場合は、そのバックアップに目を通し、そこからファイルを取り出すのが便利な場合があります。

場合によっては、ファイルの価値が低いと判断され、レコードを削除する価値があるかもしれません。

Geo 自体は、プライマリでファイルがなくなった場合の優れた緩和策です。プライマリでファイルが消えても、セカンダリに同期済みであれば、セカンダリのファイルを取得できます。このような場合、File is not checksummable のエラーメッセージは Geo セカンダリサイトでは発生せず、プライマリのみがこのエラーメッセージを記録します。

この問題は、オリジナルのGitLabサイトのかなり後に設定されたGeoセカンダリサイトで現れやすくなります。この場合、Geoは既存の問題を表面化しているだけです。

この動作はGitLab 14.6までの以下のデータタイプにのみ影響します:

データ型バージョン
パッケージ・レジストリ13.10
CIパイプラインアーティファクト13.11
Terraformステートバージョン13.12
Infrastructure Registry (GitLab 15.11でTerraform Module Registryに名称変更)14.0
外部 MR の差分14.6
LFS オブジェクト14.6
ページのデプロイ14.6
アップロードファイル14.6
CI ジョブ アーティファクト14.6

GitLab 14.7 以降、プライマリサイトで見つからないファイルは同期失敗として扱われ、Geo はデータ損失のリスクを目に見える形で表面化するようになりました。そのため、同期と検証のループが短絡的になります。last_sync_failureThe file is missing on the Geo primary siteに設定されました。

GitLab管理オブジェクトストレージレプリケーションでの同期失敗

GitLab 14.2 から 14.7 では、GitLab が管理するオブジェクトストレージのレプリケーションが使用されている場合に Geo に影響するイシューがあり、blob オブジェクトタイプの同期に失敗することがあります。

GitLab 14.2以降、検証に失敗すると同期に失敗し、これらのオブジェクトの再同期が発生します。

オブジェクトストレージに保存されたファイルに対しては検証が実装されていないため(詳細はイシュー13845を参照)、オブジェクトストレージに保存されたすべてのオブジェクトに対して一貫して失敗するループが発生します。

オブジェクトを同期済みとしてマークし、検証を成功させることでこれを回避できますが、プライマリから欠落しているオブジェクトもマークされる可能性があることに注意してください。

これを行うには、Railsコンソールに入り、以下を実行します:

Gitlab::Geo.verification_enabled_replicator_classes.each do |klass|
  updated = klass.registry_class.failed.where(last_sync_failure: "Verification failed with: Error during verification: File is not checksummable").update_all(verification_checksum: '0000000000000000000000000000000000000000', verification_state: 2, verification_failure: nil, verification_retry_at: nil, state: 2, last_sync_failure: nil, retry_at: nil, verification_retry_count: 0, retry_count: 0)
  pp "Updated #{updated} #{klass.replicable_name_plural}"
end

メッセージ: curl 18 転送は、未処理の読み込みデータが残っている状態で終了しました。

不安定なネットワーク環境では、プライマリサイトから大きなリポジトリデータをフェッチしようとしたときに、Gitalyが失敗することがあります。これは、リポジトリがサイト間でゼロから複製されなければならない場合に起こりやすくなります。

Geoは何度か再試行しますが、ネットワークの不調によって転送が常に中断される場合は、git を回避し、Geoによる複製に失敗したリポジトリの初期コピーを作成するために、rsync のような別の方法を使用することができます。

失敗したリポジトリを個別に転送し、各転送後に整合性をチェックすることをお勧めします。シングルターゲットrsync 指示 に従って、影響を受ける各リポジトリをプライマリ サイトからセカンダリ サイトに転送します。

プロジェクトまたはプロジェクトWikiリポジトリ

リポジトリの検証失敗の検索

セカンダリGeoサイトでRailsコンソールセッションを開始し、詳細な情報を収集します。

caution
データを変更するコマンドは、正しく実行しなかったり適切な条件下で実行しなかったりすると、ダメージを与える可能性があります。必ず最初にテスト環境でコマンドを実行し、リストアできるようにバックアップインスタンスを用意してください。
検証失敗リポジトリ数の取得
Geo::ProjectRegistry.verification_failed('repository').count
検証に失敗したリポジトリの検索
Geo::ProjectRegistry.verification_failed('repository')
同期に失敗したリポジトリの検索
Geo::ProjectRegistry.sync_failed('repository')

プロジェクトとプロジェクトWikiリポジトリの再同期

セカンダリGeoサイトでRailsコンソールセッションを開始し、以下の変更を実行します。

caution
データを変更するコマンドは、正しく実行しなかったり適切な条件下で実行しなかったりすると、ダメージを与える可能性があります。必ず最初にテスト環境でコマンドを実行し、リストアできるようにバックアップインスタンスを用意してください。
再同期のためにすべてのリポジトリをキューに入れます。

これを実行すると、同期がSidekiqによってバックグラウンドで処理されます。

Geo::ProjectRegistry.update_all(resync_repository: true, resync_wiki: true)
今すぐリポジトリを同期
project = Project.find_by_full_path('<group/project>')

Geo::RepositorySyncService.new(project).execute
すべての失敗したリポジトリを今すぐ同期

以下のスクリプト:

  • 現在失敗しているすべてのリポジトリをループします。
  • プロジェクトの詳細と最後に失敗した理由を表示します。
  • リポジトリの再同期を試みます。
  • 失敗した場合、その理由をレポーターします。
Geo::ProjectRegistry.sync_failed('repository').find_each do |p|
   begin
     project = p.project
     puts "#{project.full_path} | id: #{p.project_id} | last error: '#{p.last_repository_sync_failure}'"
     Geo::RepositorySyncService.new(project).execute
   rescue => e
     puts "ID: #{p.project_id} failed: '#{e}'", e.backtrace.join("\n")
   end
end ; nil

Geo セカンダリサイトのリポジトリチェック失敗の検索

すべてのプロジェクトで有効にすると、リポジトリチェックはGeo セカンダリサイトでも実行されます。メタデータは Geo トラッキングデータベースに保存されます。

Geo セカンダリサイトでのリポジトリチェックの失敗は、必ずしもレプリケーションの問題を意味するわけではありません。ここでは、これらの失敗を解決するための一般的な方法を説明します。

  1. 以下に示すように、影響を受けるリポジトリとそのログに記録されたエラーを検索します。
  2. 特定のgit fsck エラーを診断してみてください。考えられるエラーの範囲は広いので、検索エンジンで検索してみてください。
  3. 影響を受けるリポジトリの典型的な機能をテストしてください。セカンダリからプルして、ファイルを見てください。
  4. プライマリサイトのリポジトリコピーに同一のgit fsck エラーがあるかどうかを確認します。フェイルオーバーを計画している場合は、セカンダリサイトがプライマリサイトと同じ情報を持っていることを優先してください。プライマリのバックアップがあることを確認し、計画されたフェイルオーバーのガイドラインに従ってください。
  5. プライマリにプッシュし、変更がセカンダリサイトにレプリケートされるか確認します。
  6. レプリケーションが自動的に行われない場合は、リポジトリを手動で同期してみてください。

Railsコンソールセッションを起動して、以下の基本的なトラブルシューティング手順を実行します。

caution
データを変更するコマンドは、正しく実行しなかったり適切な条件下で実行しなかったりすると、ダメージを与える可能性があります。必ず最初にテスト環境でコマンドを実行し、リストアできるようにバックアップインスタンスを用意してください。

リポジトリチェックに失敗したリポジトリの数を取得します。

Geo::ProjectRegistry.where(last_repository_check_failed: true).count

リポジトリチェックに失敗したリポジトリの検索

Geo::ProjectRegistry.where(last_repository_check_failed: true)

リポジトリチェックに失敗したリポジトリの再チェック

これを実行すると、失敗した各リポジトリに対してfsck が実行されます。

fsck Rake コマンド をセカンダリサイトで使用することで、リポジトリのチェックが失敗する理由を把握することができます。

Geo::ProjectRegistry.where(last_repository_check_failed: true).each do |pr|
    RepositoryCheck::SingleRepositoryWorker.new.perform(pr.project_id)
end

PostgreSQL以外のレプリケーション失敗の修正

Admin > Geo > Sites 、または同期ステータスRakeタスクでレプリケーションの失敗が発生した場合、以下の一般的な手順で失敗を解決することができます:

  1. Geo は自動的に失敗を再試行します。失敗が新しく数が少ない場合、または根本的な原因がすでに解決されていると思われる場合は、失敗がなくなるまで待つことができます。
  2. 障害が長期間発生している場合は、すでに多くの再試行が行われており、自動再試行の間隔は障害の種類に応じて最大 4 時間まで延びています。根本的な原因がすでに解決されていると思われる場合は、手動でレプリケーションまたは検証を再試行できます。
  3. 障害が続く場合は、以下のセクションを使用して障害の解決を試みてください。

手動でレプリケーションまたは検証を再試行します。

プロジェクト Git リポジトリとプロジェクト Wiki Git リポジトリには、Admin > Geo > ReplicationResync allReverify all、単一のリソースについてはResyncReverifyの機能があります。

他のデータ型にこの機能を追加することは、イシュー364725で提案されています。

以下のセクションでは、Railsコンソールで内部アプリケーションコマンドを使用してレプリケーションや検証を即座に実行する方法について説明します。

caution
データを変更するコマンドは、正しく実行しなかったり適切な条件下で実行しなかったりすると、ダメージを与える可能性があります。必ず最初にテスト環境でコマンドを実行し、リストアできるようにバックアップインスタンスを用意してください。

ブロブタイプ

  • Ci::JobArtifact
  • Ci::PipelineArtifact
  • Ci::SecureFile
  • LfsObject
  • MergeRequestDiff
  • Packages::PackageFile
  • PagesDeployment
  • Terraform::StateVersion
  • Upload

Packages::PackageFile は以下のRailsコンソールの例で使用されていますが、他の型でも概ね同じように動作します。

caution
データを変更するコマンドは、正しく実行しなかったり適切な条件下で実行しなかったりすると、ダメージを与える可能性があります。必ず最初にテスト環境でコマンドを実行し、リストアできるようにバックアップインスタンスを用意してください。

プロジェクトまたはプロジェクトWikiリポジトリを除くリポジトリの種類

  • SnippetRepository
  • GroupWikiRepository

SnippetRepository は以下の例で使用されていますが、他のリポジトリタイプでも一般的に同じように動作します。

Railsコンソールセッションを起動して、以下の基本的なトラブルシューティング手順を実行します。

caution
データを変更するコマンドは、正しく実行しなかったり適切な条件下で実行しなかったりすると、ダメージを与える可能性があります。必ず最初にテスト環境でコマンドを実行し、リストアできるようにバックアップインスタンスを用意してください。

レプリケーター

主なクラスの種類はレジストリ、モデル、レプリケーターです。これらのクラスのインスタンスがあれば、他のクラスを取得することができます。レジストリとモデルは主にPostgreSQL DBの状態を管理します。レプリケータはレプリケーションや検証の方法を知っています(あるいは、サービスを呼び出して行うこともできます):

model_record = Packages::PackageFile.last
model_record.replicator.registry.replicator.model_record # just showing that these methods exist

IDを指定してパッケージファイルを同期的に複製します。

model_record = Packages::PackageFile.find(id)
model_record.replicator.send(:download)

レジストリIDを指定して、パッケージファイルを同期的に複製します。

registry = Geo::PackageFileRegistry.find(registry_id)
registry.replicator.send(:download)

同期に失敗したblobのレジストリ記録の検索

Geo::PackageFileRegistry.failed

プライマリサイトで見つからないblobのレジストリレコードの検索

Geo::PackageFileRegistry.where(last_sync_failure: 'The file is missing on the Geo primary site')

セカンダリのパッケージ・ファイルを手動で検証

これはセカンダリ上のすべてのパッケージファイルを繰り返し、データベースに保存されているverification_checksum (これはプライマリから来たものです) を見て、セカンダリ上でこの値を計算し、一致するかどうかをチェックします。これは UI では何も変更しません。

GitLab 14.4以降用:

# Run on secondary
status = {}

Packages::PackageFile.find_each do |package_file|
  primary_checksum = package_file.verification_checksum
  secondary_checksum = Packages::PackageFile.sha256_hexdigest(package_file.file.path)
  verification_status = (primary_checksum == secondary_checksum)

  status[verification_status.to_s] ||= []
  status[verification_status.to_s] << package_file.id
end

# Count how many of each value we get
status.keys.each {|key| puts "#{key} count: #{status[key].count}"}

# See the output in its entirety
status

GitLab 14.3以前の場合:

# Run on secondary
status = {}

Packages::PackageFile.find_each do |package_file|
  primary_checksum = package_file.verification_checksum
  secondary_checksum = Packages::PackageFile.hexdigest(package_file.file.path)
  verification_status = (primary_checksum == secondary_checksum)

  status[verification_status.to_s] ||= []
  status[verification_status.to_s] << package_file.id
end

# Count how many of each value we get
status.keys.each {|key| puts "#{key} count: #{status[key].count}"}

# See the output in its entirety
status

すべてのアップロード(または検証されたSSFデータ型)を元に戻します。

  1. プライマリGeoサイトのGitLab RailsノードにSSH接続します。
  2. Railsコンソールを開きます。
  3. すべてのアップロードを “pending verification” としてマークします:

    Upload.verification_state_table_class.each_batch do |relation|
      relation.update_all(verification_state: 0)
    end
    
  4. これにより、プライマリがすべてのアップロードのチェックサムを開始します。
  5. プライマリがレコードのチェックサムに成功すると、すべてのセカンダリも同様にチェックサムを再計算し、その値を比較します。

他の SSF データ型については、上記のコマンドのUpload を希望のモデルクラスに置き換えてください。

HTTPレスポンスコードエラー

セカンダリサイトがGeoプロキシで502エラーを返します。

セカンダリサイトのGeoプロキシが有効で、セカンダリサイトのユーザーインターフェイスが502エラーを返す場合、プライマリサイトからプロキシされたレスポンスヘッダが大きすぎる可能性があります。

NGINX のログにこの例と同様のエラーがないか確認してください:

2022/01/26 00:02:13 [error] 26641#0: *829148 upstream sent too big header while reading response header from upstream, client: 10.0.2.2, server: geo.staging.gitlab.com, request: "POST /users/sign_in HTTP/2.0", upstream: "http://unix:/var/opt/gitlab/gitlab-workhorse/sockets/socket:/users/sign_in", host: "geo.staging.gitlab.com", referrer: "https://geo.staging.gitlab.com/users/sign_in"

このイシューを解決するには、以下の手順に従ってください:

  1. セカンダリサイトのすべてのウェブノードの/etc/gitlab.rbnginx['proxy_custom_buffer_size'] = '8k' を設定します。
  2. sudo gitlab-ctl reconfigure を使用してセカンダリを再設定します。

それでもこのエラーが発生する場合は、上記の手順を繰り返し、8k のサイズを変更することで、バッファサイズをさらに大きくすることができます。たとえば、16k のサイズを 2 倍にします。

Geo Admin Area に健康状態が ‘Unknown’ と表示され、’Request failed with status code 401’ と表示されます。

ロードバランサーを使用している場合、ロードバランサーの URL がロードバランサーの背後にあるノードの/etc/gitlab/gitlab.rbexternal_url として設定されていることを確認してください。

プライマリサイトがアクセス時に 500 エラーを返します。/admin/geo/replication/projects

プライマリの Geo サイトでAdmin > Geo > Replication(または/admin/geo/replication/projects) に移動すると 500 エラーが表示されますが、セカンダリの同じリンクは問題なく動作します。プライマリのproduction.log には以下のようなエントリがあります:

Geo::TrackingBase::SecondaryNotConfigured: Geo secondary database is not configured
  from ee/app/models/geo/tracking_base.rb:26:in `connection'
  [..]
  from ee/app/views/admin/geo/projects/_all.html.haml:1

Geo プライマリサイトでは、このエラーは無視できます。

これは GitLab がプライマリサイトに存在しないGeo トラッキングデータベースからレジストリを表示しようとしているために起こります(プライマリに存在するのはオリジナルのプロジェクトだけで、複製されたプロジェクトは存在せず、したがってトラッキングデータベースも存在しません)。

このエラーは、プライマリサイトの内部URLが正しくない場合に発生する可能性があります。

たとえば、統一URLを使用していて、プライマリ・サイトの内部URLも外部URLと等しい場合です。これにより、セカンダリサイトがプライマリサイトの内部URLへのリクエストをプロキシするときにループが発生します。

このイシューを解決するには、プライマリ・サイトの内部URLを次のようなURLに設定します:

  • プライマリ・サイト固有のものです。
  • すべてのセカンダリーサイトからアクセス可能。
  1. プライマリサイトをご覧ください。
  2. 内部URLを設定します。

セカンダリサイトのリターンReceived HTTP code 403 from proxy after CONNECT

Linux パッケージ (Omnibus) を使って GitLab をインストールし、Gitaly 用のカスタム環境変数 no_proxy を設定している場合、このイシューが発生する可能性があります。影響を受けるバージョン

  • 15.4.6
  • 15.5.0-15.5.6
  • 15.6.0-15.6.3
  • 15.7.0-15.7.1

これは Linux パッケージ 15.4.6 以降に同梱されている cURL のバージョンにバグがあるためです。このバグが修正された後のバージョンにアップグレードしてください。

このバグは、no_proxy 環境変数リストの最後の on 以外、すべてのワイルドカードドメイン (.example.com) を無視する原因となります。したがって、何らかの理由で新しいバージョンにアップグレードできない場合は、 ワイルドカードドメインをリストの最後に移動することで、この問題を回避できます:

  1. /etc/gitlab/gitlab.rb を編集します:

    gitaly['env'] = {
      "no_proxy" => "sever.yourdomain.org, .yourdomain.com",
    }
    
  2. GitLab を再設定します:

    sudo gitlab-ctl reconfigure
    

no_proxy リストにワイルドカードドメインを1つだけ持つことができます。

Geo 管理エリアがセカンダリサイトに対して 404 エラーを返します。

sudo gitlab-rake gitlab:geo:checkセカンダリサイトの Rails ノードが正常であることを示していますが、プライマリサイトのウェブ インターフェイスの Geo Admin Area でセカンダリサイトの 404 Not Found エラー メッセージが返されることがあります。

このイシューを解決するには、以下の手順に従ってください:

  • sudo gitlab-ctl restart を使用して、セカンダリサイトの各 Rails、Sidekiq、Gitaly ノードを再起動してみてください。
  • Sidekiqノードの/var/log/gitlab/gitlab-rails/geo.logセカンダリサイトが プライマリサイトにステータスを送信するためにIPv6を使用しているかどうかを確認します。使用している場合は、/etc/hosts ファイルに IPv4 を使用するプライマリサイトのエントリを追加します。または、プライマリサイトでIPv6を有効にする必要があります。

一般的なエラーの修正

このセクションでは、ウェブインターフェースの管理エリアでレポーターが報告する一般的なエラーメッセージとその修正方法について説明します。

Geo データベース設定ファイルがありません。

GitLab がdatabase_geo.yml 設定ファイルを見つけられないか、アクセス権限がありません。

Linux パッケージのインストールでは、このファイルは/var/opt/gitlab/gitlab-rails/etc にあるはずです。存在しない場合や、不注意で変更されてしまった場合は、sudo gitlab-ctl reconfigure を実行して正しい状態に戻してください。

このパスがリモートボリュームにマウントされている場合は、ボリューム設定に正しい権限があることを確認してください。

既存の追跡データベースを再利用できません

Geo は既存のトラッキングデータベースを再利用することはできません。

新しいセカンダリを使用するか、Geo セカンダリサイトレプリケーションのリセットに従ってセカンダリ全体をリセットするのが最も安全です。

Geo サイトに書き込み可能なデータベースがありますが、これはプライマリ サイトとのレプリケーションが設定されていないことを示しています。

このエラーメッセージは、Geo がアクセスを期待しているセカンダリサイトのデータベースレプリカに問題があることを示しています。これは通常、以下のどちらかを意味します:

  • サポートされていないレプリケーション方法(論理レプリケーションなど)が使用されました。
  • Geo データベースのレプリケーションをセットアップする手順が正しく実行されていません。
  • データベース接続の詳細が正しくありません。つまり、/etc/gitlab/gitlab.rb ファイルで間違ったユーザーを指定しています。

Geoセカンダリサイトには、2 つの別々の PostgreSQL インスタンスが必要です:

  • プライマリサイトの読み取り専用レプリカ。
  • レプリケーションのメタデータを保持する書き込み可能な通常のインスタンス。つまり、Geo追跡データベース。

このエラーメッセージは、セカンダリサイトのレプリカ データベースの設定が誤っており、レプリケーションが停止していることを示しています。

データベースを復元してレプリケーションを再開するには、次のいずれかを実行します:

新しいセカンダリをゼロからセットアップする場合は、古いサイトも Geo クラスターから削除する必要があります。

Geo サイトがプライマリ サイトからデータベースをレプリケートしていないようです。

データベースが正しく複製されない最も一般的な問題は次のとおりです:

  • セカンダリ・サイトが プライマリ・サイトにアクセスできない認証情報とファイアウォール・ルールを確認してください。
  • SSL証明書の問題。プライマリ・サイトから /etc/gitlab/gitlab-secrets.json をコピーしたことを確認してください。
  • データベース・ストレージ・ディスクが一杯です。
  • データベースのレプリケーションスロットが誤って設定されています。
  • データベースがレプリケーション・スロットまたは別の代替手段を使用しておらず、WAL ファイルがパージされたためキャッチアップできません。

サポートされている設定について、Geo データベース・レプリケーションの説明に従っていることを確認してください。

Geo データベースのバージョン (…) が最新のマイグレーション (…) と一致しません。

Linux パッケージインストールを使用している場合、アップグレード中に何かが失敗した可能性があります。可能です:

  • sudo gitlab-ctl reconfigure を実行してください。
  • セカンダリサイトのroot 権限でsudo gitlab-rake db:migrate:geo を実行して、手動でデータベースマイグレーションを起動します。

GitLab はリポジトリの同期が 100% 以上行われたことを示しています。

これは、プロジェクトレジストリの孤立したレコードが原因の可能性があります。Rake タスクでプロジェクトレジストリを削除することで、これを取り除くことができます。

プライマリサイトのexternal_url の値を変更すると、セカンダリサイトが UI で “Unhealthy” と表示されます。

プライマリサイトの/etc/gitlab/gitlab.rbexternal_url の値を更新した場合、またはプロトコルをhttp からhttpsに変更した場合、セカンダリサイトがUnhealthyとして表示されることがあります。また、geo.logに次のようなエラーが表示されることがあります:

"class": "Geo::NodeStatusRequestService",
...
"message": "Failed to Net::HTTP::Post to primary url: http://primary-site.gitlab.tld/api/v4/geo/status",
  "error": "Failed to open TCP connection to <PRIMARY_IP_ADDRESS>:80 (Connection refused - connect(2) for \"<PRIMARY_ID_ADDRESS>\" port 80)"

この場合、すべてのサイトで変更したURLを更新してください:

  1. 左のサイドバーで、Search を選択するか、次のページに進んでください。
  2. Admin Areaを選択します。
  3. 左サイドバーでGeo > Sites を選択します。
  4. URLを変更し、変更を保存します。

メッセージ:ERROR: canceling statement due to conflict with recovery バックアップ中

Geoセカンダリでバックアップを実行することはサポートされていません。

セカンダリでバックアップを実行すると、以下のエラーメッセージが表示されることがあります:

Dumping PostgreSQL database gitlabhq_production ...
pg_dump: error: Dumping the contents of table "notes" failed: PQgetResult() failed.
pg_dump: error: Error message from server: ERROR:  canceling statement due to conflict with recovery
DETAIL:  User query might have needed to see row versions that must be removed.
pg_dump: error: The command was: COPY public.notes (id, note, [...], last_edited_at) TO stdout;

GeoセカンダリのGitLabアップグレード中にデータベースのバックアップが自動的に作成されないようにするには、以下の空のファイルを作成してください:

sudo touch /etc/gitlab/skip-auto-backup

フェイルオーバー中やセカンダリをプライマリサイトに昇格させる際のエラーの修正

以下は、フェイルオーバー中またはセカンダリ・サイトをプライマリ・サイトに昇格させる際に発生する可能性のあるエラー・メッセージと、その解決策です。

メッセージActiveRecord::RecordInvalid: Validation failed: Name has already been taken

セカンダリー・サイトを昇格させる際、以下のエラー・メッセージが表示されることがあります:

Running gitlab-rake geo:set_secondary_as_primary...

rake aborted!
ActiveRecord::RecordInvalid: Validation failed: Name has already been taken
/opt/gitlab/embedded/service/gitlab-rails/ee/lib/tasks/geo.rake:236:in `block (3 levels) in <top (required)>'
/opt/gitlab/embedded/service/gitlab-rails/ee/lib/tasks/geo.rake:221:in `block (2 levels) in <top (required)>'
/opt/gitlab/embedded/bin/bundle:23:in `load'
/opt/gitlab/embedded/bin/bundle:23:in `<main>'
Tasks: TOP => geo:set_secondary_as_primary
(See full trace by running task with --trace)

You successfully promoted this node!

gitlab-rake geo:set_secondary_as_primary またはgitlab-ctl promote-to-primary-node を実行中にこのメッセージが表示された場合は、次のどちらかを実行してください:

  • Railsコンソールに入って実行します:

     Rails.application.load_tasks; nil
     Gitlab::Geo.expire_cache!
     Rake::Task['geo:set_secondary_as_primary'].invoke
    
  • 安全であれば、GitLab 12.6.3以降にアップグレードしてください。例えば、フェイルオーバーが単なるテストだった場合。キャッシュ関連のバグを修正しました。

メッセージNoMethodError: undefined method `secondary?' for nil:NilClass

セカンダリー・サイトを昇格させる際、以下のエラー・メッセージが表示されることがあります:

sudo gitlab-rake geo:set_secondary_as_primary

rake aborted!
NoMethodError: undefined method `secondary?' for nil:NilClass
/opt/gitlab/embedded/service/gitlab-rails/ee/lib/tasks/geo.rake:232:in `block (3 levels) in <top (required)>'
/opt/gitlab/embedded/service/gitlab-rails/ee/lib/tasks/geo.rake:221:in `block (2 levels) in <top (required)>'
/opt/gitlab/embedded/bin/bundle:23:in `load'
/opt/gitlab/embedded/bin/bundle:23:in `<main>'
Tasks: TOP => geo:set_secondary_as_primary
(See full trace by running task with --trace)

このコマンドはセカンダリ サイトでのみ実行することを意図しています。プライマリ サイトでこのコマンドを実行しようとすると、このエラー メッセージが表示されます。

期限切れのアーティファクト

何らかの理由で Geoセカンダリサイトに Geoプライマリサイトよりも多くのアーティファクトがあることに気づいた場合、Rake タスクを使用して、オーファン アーティファクト ファイルをクリーンアップできます。

Geoセカンダリーサイトでは、このコマンドはディスク上の孤児ファイルに関連するすべての Geo レジストリ記録もクリーンアップします。

サインインエラーの修正

メッセージリダイレクトURIが無効です

プライマリサイトの Web インターフェイスにサインインできるにもかかわらず、セカンダリWeb インターフェイスにサインインしようとするとこのエラー メッセージが表示される場合は、Geo サイトの URL が外部 URL と一致していることを確認する必要があります。

プライマリサイトで

  1. 左のサイドバーで、Search を選択するか、次のページに進んでください。
  2. Admin Areaを選択します。
  3. 左サイドバーでGeo > Sites を選択します。
  4. 影響を受けるセカンダリー・サイトを見つけ、[Edit] を選択します。
  5. URLフィールドがセカンダリサイトの Rails ノードの external_url "https://gitlab.example.com"/etc/gitlab/gitlab.rb にある値と一致していることを確認します。

セカンダリサイトで SAML を使用して認証すると、常にプライマリサイトに着陸します。

この問題は通常、GitLab 15.1にアップグレードしたときに発生します。この問題を解決するには、Geo with Single Sign-OnでインスタンスワイドSAMLを設定するをご覧ください。

クライアントエラーの修正

LFS HTTP(S) クライアントリクエストによる作成者エラー

Git LFSのバージョンが 2.4.2 より前の場合は、問題が発生する可能性があります。この認証のイシューにあるように、セカンダリサイトからプライマリサイトにリダイレクトされたリクエストは Authorization ヘッダを正しく送信しません。その結果、Authorization <-> Redirect が無限にループしたり Authorization のエラーメッセージが表示されたりします。

エラー:.NET::ReadTimeout(GeoセカンダリのSSH経由でプッシュする場合

GeoセカンダリサイトでSSH経由で大きなリポジトリをプッシュすると、タイムアウトが発生することがあります。これは、Railsがプッシュをプライマリにプロキシし、このGeoイシューで説明されているようにデフォルトのタイムアウトが60秒に設定されているためです。

現在の回避策は以下のとおりです:

  • Workhorseがリクエストをプライマリにプロキシします(Geoプロキシが有効でない場合はプライマリにリダイレクトします)。
  • プライマリに直接プッシュします。

ログ例 (gitlab-shell.log):

Failed to contact primary https://primary.domain.com/namespace/push_test.git\\nError: Net::ReadTimeout\",\"result\":null}" code=500 method=POST pid=5483 url="http://127.0.0.1:3000/api/v4/geo/proxy_git_push_ssh/push"

部分的なフェイルオーバーからの回復

セカンダリ Geoサイトへの部分的なフェイルオーバーは、一時的または一時的なイシューの結果である可能性があります。そのため、まず昇格コマンドの再実行を試みてください。

  1. セカンダリサイトのすべての Sidekiq、PostgreSQL、Gitaly、および Rails ノードに SSH でログインし、次のコマンドのいずれかを実行します:

    • セカンダリサイトをプライマリに昇格させるには、次のコマンドを実行します:

       sudo gitlab-ctl geo promote
      
    • セカンダリ・サイトをプライマリに昇格させる: セカンダリ・サイトをプライマリに昇格させる場合は、次の手順を実行します:

       sudo gitlab-ctl geo promote --force
      
  2. 新しく昇格させたプライマリサイトにセカンダリサイトで以前使用していた URL で接続できることを確認します。
  3. 成功すると、セカンダリサイトが プライマリサイトに昇格されます。

上記の手順が成功しなかった場合は、次の手順に進んでください:

  1. セカンダリサイトのすべてのSidekiq、PostgreSQL、Gitaly、RailsノードにSSH接続して、次のオペレーションを実行します:

    • 以下の内容で/etc/gitlab/gitlab-cluster.json

       {
         "primary": true,
         "secondary": false
       }
      
    • 変更を有効にするために GitLab を再設定します:

       sudo gitlab-ctl reconfigure
      
  2. 新しく昇格させたプライマリサイトにセカンダリサイトで以前使用していた URL で接続できることを確認します。
  3. 成功すると、セカンダリサイトが プライマリサイトに昇格されます。

データベースのレプリケーション遅延の原因の調査

sudo gitlab-rake geo:status の出力で、Database replication lag が時間の経過とともに著しく高いままになっている場合、データベースレプリケーションのプライマリノードをチェックして、データベースレプリケーションプロセスのさまざまな部分のラグの状態を判断することができます。これらの値はwrite_lagflush_lagreplay_lagとして知られています。詳細はPostgreSQLの公式ドキュメントを参照してください。

プライマリノードのデータベースから以下のコマンドを実行すると、関連する出力が得られます:

gitlab-psql -xc 'SELECT write_lag,flush_lag,replay_lag FROM pg_stat_replication;'

-[ RECORD 1 ]---------------
write_lag  | 00:00:00.072392
flush_lag  | 00:00:00.108168
replay_lag | 00:00:00.108283

これらの値の 1 つ以上が著しく高い場合は、問題がある可能性があるため、さらに調査する必要があります。原因を特定する際には、以下の点を考慮してください:

  • write_lag は、WAL バイトがプライマリから送信され、セカンダリに受信されたが、まだフラッシュまたは適用されていない状態からの時間を示します。
  • write_lag の値が高い場合は、プライマリノードとセカンダリノード間のネットワークパフォーマンスが低下しているか、ネットワーク速度が不十分である可能性があります。
  • flush_lag の値が高い場合、セカンダリノードのストレージデバイスのディスクI/Oパフォーマンスが低下しているか、最適でない可能性があります。
  • replay_lag の値が高い場合、PostgreSQLのトランザクションが長時間実行されているか、CPUのような必要なリソースが飽和している可能性があります。
  • write_lagflush_lag の時間差は、WALバイトが内部ストレージシステムに送信されたが、フラッシュされたことがレポーターされていないことを示しています。このデータは永続ストレージに完全に書き込まれておらず、何らかの揮発性書き込みキャッシュに保持されている可能性が高いです。
  • flush_lagreplay_lag の差は、WAL バイトがストレージに正常に永続化されたが、データベース システムによって再生できなかったことを示します。

Geoセカンダリサイト レプリケーションのリセット

セカンダリサイトが壊れた状態になり、レプリケーションの状態をリセットして最初からやり直したい場合、役立つ手順がいくつかあります:

  1. Sidekiq と Geo LogCursor を停止します。

    Sidekiqを優雅に停止させることは可能ですが、新しいジョブの取得を停止し、現在のジョブが処理を終えるまで待機させます。

    最初のフェーズではSIGTSTPkillシグナルを送信し、すべてのジョブが終了したらSIGTERMを送信する必要があります。それ以外の場合は、gitlab-ctl stop コマンドを使ってください。

    gitlab-ctl status sidekiq
    # run: sidekiq: (pid 10180) <- this is the PID you will use
    kill -TSTP 10180 # change to the correct PID
       
    gitlab-ctl stop sidekiq
    gitlab-ctl stop geo-logcursor
    

    Sidekiqジョブの処理が終了したことを知るには、Sidekiqログを見ることができます:

    gitlab-ctl tail sidekiq
    
  2. リポジトリストレージフォルダの名前を変更し、新しいフォルダを作成します。ディレクトリやファイルが取り残される可能性があることを気にしない場合は、この手順をスキップできます。

    mv /var/opt/gitlab/git-data/repositories /var/opt/gitlab/git-data/repositories.old
    mkdir -p /var/opt/gitlab/git-data/repositories
    chown git:git /var/opt/gitlab/git-data/repositories
    
    note
    将来、ディスクスペースを節約するために、不要になったことを確認したらすぐに/var/opt/gitlab/git-data/repositories.old を削除したいかもしれません。
  3. オプション。他のデータフォルダの名前を変更し、新しいフォルダを作成します。

    caution
    プライマリサイトから削除されたファイルがセカンダリサイトに残っている可能性がありますが、この削除は反映されていません。この手順をスキップすると、これらのファイルは Geoセカンダリサイトから削除されません。

    アップロードされたコンテンツ(添付ファイル、アバター、LFS オブジェクトなど)は、これらのパスのいずれかのサブフォルダに保存されます:

    • /var/opt/gitlab/gitlab-rails/shared
    • /var/opt/gitlab/gitlab-rails/uploads

    すべての名前を変更するには

    gitlab-ctl stop
       
    mv /var/opt/gitlab/gitlab-rails/shared /var/opt/gitlab/gitlab-rails/shared.old
    mkdir -p /var/opt/gitlab/gitlab-rails/shared
       
    mv /var/opt/gitlab/gitlab-rails/uploads /var/opt/gitlab/gitlab-rails/uploads.old
    mkdir -p /var/opt/gitlab/gitlab-rails/uploads
       
    gitlab-ctl start postgresql
    gitlab-ctl start geo-postgresql
    

    フォルダを再構成し、権限と所有者が正しいことを確認します:

    gitlab-ctl reconfigure
    
  4. トラッキング・データベースをリセットします。

    caution
    オプションのステップ 3 を省略した場合は、geo-postgresqlpostgresql の両方のサービスが実行されていることを確認してください。
    gitlab-rake db:drop:geo DISABLE_DATABASE_ENVIRONMENT_CHECK=1   # on a secondary app node
    gitlab-ctl reconfigure     # on the tracking database node
    gitlab-rake db:migrate:geo # on a secondary app node
    
  5. 以前に停止したサービスを再起動します。

    gitlab-ctl start