LinuxパッケージインストールのPostgreSQLレプリケーションとフェイルオーバーのトラブルシューティング
- プラン: Premium、Ultimate
- 提供形態: GitLab Self-Managed
PostgreSQLのレプリケーションおよびフェイルオーバーを使用する際に、以下の問題が発生する可能性があります。
ConsulとPostgreSQLの変更が適用されない
潜在的な影響を考慮して、gitlab-ctl reconfigureはConsulとPostgreSQLをリロードするだけで、サービスを再起動しません。しかし、すべての変更がリロードによって有効になるわけではありません。
いずれかのサービスを再起動するには、gitlab-ctl restart SERVICEを実行してください。
PostgreSQLの場合、デフォルトではリーダーノードの再起動は通常安全です。自動フェイルオーバーは、タイムアウトが1分にデフォルト設定されています。データベースがそれまでに復旧すれば、他に何もする必要はありません。
Consulサーバーノードでは、制御された方法でConsulサービスを再起動することが重要です。
PgBouncerエラーERROR: pgbouncer cannot connect to server
gitlab-rake gitlab:db:configureの実行中にこのエラーが発生するか、PgBouncerのログファイルにエラーが表示される場合があります。
PG::ConnectionBad: ERROR: pgbouncer cannot connect to server問題は、データベースノード上の/etc/gitlab/gitlab.rbのtrust_auth_cidr_addresses設定に、PgBouncerノードのIPアドレスが含まれていないことかもしれません。
リーダーデータベースノード上のPostgreSQLログを確認することで、これが問題であることを確認できます。以下のエラーが表示された場合、trust_auth_cidr_addressesが問題です。
2018-03-29_13:59:12.11776 FATAL: no pg_hba.conf entry for host "123.123.123.123", user "pgbouncer", database "gitlabhq_production", SSL off問題を修正するには、/etc/gitlab/gitlab.rbにIPアドレスを追加します。
postgresql['trust_auth_cidr_addresses'] = %w(123.123.123.123/32 <other_cidrs>)変更を反映するためにGitLabを再設定します。
Patroniスイッチオーバー後にPgBouncerノードがフェイルオーバーしない
GitLabバージョン16.5.0より前のバージョンに影響する既知のイシューにより、Patroniスイッチオーバー後にPgBouncerノードの自動フェイルオーバーは発生しません。この例では、GitLabは一時停止されたデータベースを検出するのに失敗し、一時停止されていないデータベースをRESUMEしようとしました:
INFO -- : Running: gitlab-ctl pgb-notify --pg-database gitlabhq_production --newhost database7.example.com --user pgbouncer --hostuser gitlab-consul
ERROR -- : STDERR: Error running command: GitlabCtl::Errors::ExecutionError
ERROR -- : STDERR: ERROR: ERROR: database gitlabhq_production is not pausedPatroniスイッチオーバーを成功させるには、すべてのPgBouncerノードでPgBouncerサービスをこのコマンドで手動で再起動する必要があります:
gitlab-ctl restart pgbouncerレプリカを再初期化する
レプリカが起動できない、またはクラスターに再結合できない場合、あるいはラグが大きく追いつけない場合、レプリカを再初期化する必要があるかもしれません:
どのサーバーを再初期化する必要があるかを確認するために、レプリケーションステータスを確認します。例:
+ Cluster: postgresql-ha (6970678148837286213) ------+---------+--------------+----+-----------+ | Member | Host | Role | State | TL | Lag in MB | +-------------------------------------+--------------+---------+--------------+----+-----------+ | gitlab-database-1.example.com | 172.18.0.111 | Replica | running | 55 | 0 | | gitlab-database-2.example.com | 172.18.0.112 | Replica | start failed | | unknown | | gitlab-database-3.example.com | 172.18.0.113 | Leader | running | 55 | | +-------------------------------------+--------------+---------+--------------+----+-----------+障害が発生したサーバーにサインインし、データベースとレプリケーションを再初期化します。Patroniはそのサーバー上のPostgreSQLをシャットダウンし、データディレクトリを削除し、ゼロから再初期化します:
sudo gitlab-ctl patroni reinitialize-replica --member gitlab-database-2.example.comこれは任意のPatroniノードで実行できますが、
--memberなしのsudo gitlab-ctl patroni reinitialize-replicaは、実行されているサーバーを再起動することに注意してください。意図しないデータ損失のリスクを減らすために、障害が発生したサーバーでローカルに実行してください。ログを監視します:
sudo gitlab-ctl tail patroni
Consul内のPatroniステートをリセットする
Consul内のPatroniステートをリセットすることは、潜在的に破壊的なプロセスです。まず、健全なデータベースバックアップがあることを確認してください。
最終手段として、Consul内のPatroniステートを完全にリセットできます。
これは、Patroniクラスターが不明な状態または不良な状態であり、どのノードも起動できない場合に必要となる場合があります:
+ Cluster: postgresql-ha (6970678148837286213) ------+---------+---------+----+-----------+
| Member | Host | Role | State | TL | Lag in MB |
+-------------------------------------+--------------+---------+---------+----+-----------+
| gitlab-database-1.example.com | 172.18.0.111 | Replica | stopped | | unknown |
| gitlab-database-2.example.com | 172.18.0.112 | Replica | stopped | | unknown |
| gitlab-database-3.example.com | 172.18.0.113 | Replica | stopped | | unknown |
+-------------------------------------+--------------+---------+---------+----+-----------+Consul内のPatroniステートを削除する前に、Patroniノードでgitlab-ctlエラーを解決することを試してください。
このプロセスは、最初のPatroniノードが起動すると、再初期化されたPatroniクラスターになります。
Consul内のPatroniステートをリセットするには:
現在の状態が複数のリーダーまたはリーダーがないことを示している場合は、リーダーであったPatroniノード、またはアプリケーションが現在のリーダーと考えているPatroniノードを記録しておきます:
現在のリーダーのホスト名を含む
/var/opt/gitlab/consul/databases.iniにあるPgBouncerノードを確認します。すべてのデータベースノードのPatroniログ
/var/log/gitlab/patroni/current(または古いローテーションおよび圧縮されたログ/var/log/gitlab/patroni/@40000*) を確認して、クラスターによって最後にリーダーとして識別されたサーバーを確認します:INFO: no action. I am a secondary (database1.local) and following a leader (database2.local)
すべてのノードでPatroniを停止します:
sudo gitlab-ctl stop patroniConsul内のステートをリセットします:
/opt/gitlab/embedded/bin/consul kv delete -recurse /service/postgresql-ha/1つのPatroniノードを起動します。これにより、リーダーとして選出されるPatroniクラスターが初期化されます。最初のステップで記録した以前のリーダーを起動することを強くお勧めします。これは、破損したクラスターの状態のためにレプリケートされていない可能性のある既存の書き込みを失わないためです:
sudo gitlab-ctl start patroniPatroniクラスターにレプリカとして参加する他のすべてのPatroniノードを起動します:
sudo gitlab-ctl start patroni
引き続き問題が発生する場合は、次のステップは最後の健全なバックアップをリストアすることです。
Patroniログにおける127.0.0.1のpg_hba.confエントリに関するエラー
Patroniログ内の以下のログエントリは、レプリケーションが機能しておらず、設定変更が必要であることを示しています:
FATAL: no pg_hba.conf entry for replication connection from host "127.0.0.1", user "gitlab_replicator"問題を修正するには、ループバックインターフェースがCIDRアドレスリストに含まれていることを確認してください:
/etc/gitlab/gitlab.rbを編集します。postgresql['trust_auth_cidr_addresses'] = %w(<other_cidrs> 127.0.0.1/32)変更を反映するためにGitLabを再設定します。
すべてのレプリカが同期されていることを確認します。
Patroniメンバーが再起動保留中として表示される
gitlab-ctl patroni membersの出力には、セカンダリサイトのPatroniメンバーが再起動保留中のステータスで表示される場合があります:
secondary-site:postgresql-1> gitlab-ctl patroni members
+ Cluster: postgresql-ha ------------------------------------------------------------------+
| Member | Host | Role | State | TL | Lag in MB | Pending restart |
+----------------+-----------+----------------+---------+----+-----------+-----------------+
| patroni-1 | 10.20.0.1 | Replica | running | 27 | 0 | * |
| patroni-2 | 10.20.0.2 | Replica | running | 27 | 5 | * |
| patroni-3 | 10.20.0.3 | Standby Leader | running | 27 | | * |
+----------------+-----------+----------------+---------+----+-----------+----------再起動保留中のステータスは、これらのノードが一部の設定変更を適用するために再起動を待っていることを意味します。
これらの再起動保留中の設定が何かを知るには、確認する必要があるインスタンスで以下を実行します:
sudo gitlab-psql -c "select name, setting, short_desc, sourcefile, sourceline from pg_settings where pending_restart"保留中の設定変更を適用するには、影響を受けるノードを再起動します:
- レプリカノードの場合は、
sudo gitlab-ctl restart patroniを実行します。 - リーダーノードの場合は、まずフェイルオーバーの実行を検討するか、ダウンタイムを避けるために
sudo gitlab-ctl reload patroniを実行します。
エラー: 要求された開始ポイントが先行書き込みログ (WAL) フラッシュ位置より前にある
Patroniログのこのエラーは、データベースがレプリケートされていないことを示しています:
FATAL: could not receive data from WAL stream:
ERROR: requested starting point 0/5000000 is ahead of the WAL flush position of this server 0/4000388この例のエラーは、最初に誤って設定され、一度もレプリケートされなかったレプリカからのものです。
レプリカを再初期化して、修正します。
PatroniがMemoryErrorで起動に失敗する
Patroniが起動に失敗し、エラーとスタックトレースがログに記録されることがあります:
MemoryError
Traceback (most recent call last):
File "/opt/gitlab/embedded/bin/patroni", line 8, in <module>
sys.exit(main())
[..]
File "/opt/gitlab/embedded/lib/python3.7/ctypes/__init__.py", line 273, in _reset_cache
CFUNCTYPE(c_int)(lambda: None)スタックトレースがCFUNCTYPE(c_int)(lambda: None)で終わる場合、Linuxサーバーがセキュリティのために強化されていると、このコードはMemoryErrorをトリガーします。
このコードはPythonに一時的な実行可能ファイルを書き込ませるものであり、これが実行できるファイルシステムが見つからない場合。例えば、/tmpファイルシステムでnoexecが設定されている場合、MemoryErrorで失敗します(イシューで詳細を読む)。
gitlab-ctlの実行エラー
Patroniノードは、gitlab-ctlコマンドが失敗し、gitlab-ctl reconfigureがノードを修正できない状態になることがあります。
これがPostgreSQLのバージョンアップグレードと重なる場合は、異なる手順に従ってください。
一般的な症状の1つは、データベースサーバーが起動に失敗している場合、gitlab-ctlがインストールに必要な情報を判断できないことです:
Malformed configuration JSON file found at /opt/gitlab/embedded/nodes/<HOSTNAME>.json.
This usually happens when your last run of `gitlab-ctl reconfigure` didn't complete successfully.Error while reinitializing replica on the current node: Attributes not found in
/opt/gitlab/embedded/nodes/<HOSTNAME>.json, has reconfigure been run yet?同様に、ノードファイル (/opt/gitlab/embedded/nodes/<HOSTNAME>.json) には多くの情報が含まれているはずですが、以下のみで作成される場合があります:
{
"name": "<HOSTNAME>"
}これを修正するための以下のプロセスには、このレプリカの再初期化が含まれます: このノード上のPostgreSQLの現在の状態は破棄されます:
Patroniおよび(存在する場合は)PostgreSQLサービスをシャットダウンします:
sudo gitlab-ctl status sudo gitlab-ctl stop patroni sudo gitlab-ctl stop postgresqlPostgreSQLの起動を妨げる状態である場合に備えて、
/var/opt/gitlab/postgresql/dataを削除します:cd /var/opt/gitlab/postgresql sudo rm -rf dataデータ損失を避けるため、このステップには注意してください。このステップは、
data/の名前を変更することでも実現できます: プライマリデータベースの新しいコピーに十分な空きディスクがあることを確認し、レプリカが修正されたら余分なディレクトリを削除します。PostgreSQLが実行されていない状態で、ノードファイルが正常に作成されるようになりました:
sudo gitlab-ctl reconfigurePatroniを起動します:
sudo gitlab-ctl start patroniログを監視し、クラスターの状態を確認します:
sudo gitlab-ctl tail patroni sudo gitlab-ctl patroni membersreconfigureを再度実行します:sudo gitlab-ctl reconfiguregitlab-ctl patroni membersが必要であると示している場合は、レプリカを再初期化します:sudo gitlab-ctl patroni reinitialize-replica
この手順が機能せず、クラスターがリーダーを選出できない場合は、最終手段としてのみ使用すべき別の修正方法があります。
PatroniレプリカでのPostgreSQLメジャーバージョンアップグレードが失敗する
Patroniレプリカがgitlab-ctl pg-upgradeの実行中にループにはまり、アップグレードが失敗することがあります。
症状の例は次のとおりです:
通常Patroniノードに存在しないはずの
postgresqlサービスが定義されています。これは、gitlab-ctl pg-upgradeが新しい空のデータベースを作成するために追加するためです:run: patroni: (pid 1972) 1919s; run: log: (pid 1971) 1919s down: postgresql: 1s, normally up, want up; run: log: (pid 1973) 1919sPatroniがレプリカの再初期化の一部として
/var/opt/gitlab/postgresql/dataを削除する際に、PostgreSQLは/var/log/gitlab/postgresql/currentにPANICログエントリを生成します:DETAIL: Could not open file "pg_xact/0000": No such file or directory. WARNING: terminating connection because of crash of another server process LOG: all server processes terminated; reinitializing PANIC: could not open file "global/pg_control": No such file or directory/var/log/gitlab/patroni/currentで、Patroniは以下をログに記録します。ローカルのPostgreSQLバージョンは、クラスターリーダーとは異なります:INFO: trying to bootstrap from leader 'HOSTNAME' pg_basebackup: incompatible server version 12.6 pg_basebackup: removing data directory "/var/opt/gitlab/postgresql/data" ERROR: Error when fetching backup: pg_basebackup exited with code=1
この回避策は、Patroniクラスターが以下の状態にある場合に適用されます:
- リーダーは新しいメジャーバージョンに正常にアップグレードされました。
- レプリカ上のPostgreSQLをアップグレードするステップが失敗しています。
この回避策は、ノードを新しいPostgreSQLバージョンを使用するように設定し、リーダーがアップグレードされたときに作成された新しいクラスターでレプリカとして再初期化することにより、Patroniレプリカ上のPostgreSQLアップグレードを完了します:
すべてのノードでクラスターステータスを確認し、どれがリーダーで、レプリカがどの状態にあるかを確認します。
sudo gitlab-ctl patroni membersレプリカ: どのPostgreSQLバージョンがアクティブかを確認します:
sudo ls -al /opt/gitlab/embedded/bin | grep postgresレプリカ: ノードファイルが正しいことと、
gitlab-ctlが実行できることを確認します。これにより、レプリカにも同様のエラーがある場合、gitlab-ctlの実行エラーのイシューが解決されます:sudo gitlab-ctl stop patroni sudo gitlab-ctl reconfigureレプリカ:
incompatible server versionエラーを修正するために、PostgreSQLバイナリを必要なバージョンに再リンクします:/etc/gitlab/gitlab.rbを編集し、必要なバージョンを指定します:postgresql['version'] = 13GitLabを再設定します:
sudo gitlab-ctl reconfigureバイナリが再リンクされていることを確認します。PostgreSQL用に配布されるバイナリはメジャーリリース間で異なります。少数の誤ったシンボリックリンクがあるのが一般的です:
sudo ls -al /opt/gitlab/embedded/bin | grep postgres
レプリカ: 指定されたバージョンに対してPostgreSQLが完全に再初期化されていることを確認します:
cd /var/opt/gitlab/postgresql sudo rm -rf data sudo gitlab-ctl reconfigureレプリカ: 必要に応じて、追加の2つのターミナルセッションでデータベースを監視します:
pg_basebackupの実行に伴い、ディスク使用量が増加します。レプリカの初期化の進行状況を以下で追跡します:cd /var/opt/gitlab/postgresql watch du -sh dataログでプロセスを監視します:
sudo gitlab-ctl tail patroni
レプリカ: Patroniを起動してレプリカを再初期化します:
sudo gitlab-ctl start patroniレプリカ: 完了後、
/etc/gitlab/gitlab.rbからハードコードされたバージョンを削除します:/etc/gitlab/gitlab.rbを編集し、postgresql['version']を削除します。GitLabを再設定します:
sudo gitlab-ctl reconfigure正しいバイナリがリンクされていることを確認します:
sudo ls -al /opt/gitlab/embedded/bin | grep postgres
すべてのノードでクラスターステータスを確認します:
sudo gitlab-ctl patroni members
必要に応じて、他のレプリカでもこの手順を繰り返します。
PostgreSQLレプリカが作成中にループにはまる
PostgreSQLレプリカが移行しているように見えても、その後ループで再起動する場合は、レプリカとプライマリサーバーの/opt/gitlab-data/postgresql/フォルダーのパーミッションを確認してください。
このエラーメッセージはログにも表示されます: could not get COPY data stream: ERROR: could not open file "<file>" Permission denied。
その他のコンポーネントに関するイシュー
ここで説明されていないコンポーネントでイシューが発生した場合は、そのコンポーネントの特定のドキュメントページのトラブルシューティングセクションを必ず確認してください: