deniz.in

Piyasalar

Hava durumu

Hava durumu yükleniyor

· kaynak dev.to (home feed)

Artık bir PGPASSWORD değişkeni, eski Patroni leader'ının yeniden katılmasını engelleyebilir

Bir dev.to yazısı, Patroni süreci tarafından devralınan bir PGPASSWORD değişkeninin pg_rewind'ın kimlik doğrulama hatasıyla başarısız olmasına nasıl yol açtığını ve gerçek bir failover sonrasında eski leader'ın rehin kaldığını gösteriyor.

Artık bir PGPASSWORD değişkeni, eski Patroni leader'ının yeniden katılmasını engelleyebilir

Hata

dev.to'daki bir yazı, rutin testlerden sağlam çıkan bir Patroni hata modunu ele alıyor: bir PostgreSQL kümesi planlı her switchover'ı geçiyor, ancak leader gerçekten çöktüğünde bir replica promote ediliyor ve eski leader bir daha katılmıyor. patronictl çıktısında start failed durumunda bekliyor ve PostgreSQL logu bir timeline uyuşmazlığını tekrarlıyor: düğümün en son checkpoint'i 2. timeline'da, ama küme daha erken bir WAL konumunda 3. timeline'a dallanmış.

Bu mesaj, eski leader'ın yeni leader'ın hiç almadığı WAL yazdığı anlamına gelir; yani düğüm yeni timeline'ı basitçe takip edemez. Patroni'nin bu duruma cevabı pg_rewind'dır; düğümün veri dizinini yeni primary ile eşleşecek şekilde geri sarar. Yazarın anlattığı senaryoda, Patroni logu, pg_rewind'ın kod 1 ile çıktığını, yeni primary'nin bağlantıyı rewind_user için parola kimlik doğrulama hatasıyla reddettiğini gösteriyor. Patroni rewind'ı atlıyor ve düğümü secondary olarak başlatmayı deniyor; bu da işe yaramaz.

PGPASSWORD, .pgpass dosyasını geçersiz kılıyor

Yazıya göre Patroni parolaları komut satırında iletmez. Kimlik bilgilerini postgresql.pgpass ayarıyla kontrol edilen bir .pgpass dosyasına yazar ve pg_rewind ile pg_basebackup'ı buna yönlendirir. Sorun libpq'nun parola arama sırasıdır: bağlantı dizisindeki parola kazanır, sonra PGPASSWORD ortam değişkeni gelir ve ancak ondan sonra parola dosyası gelir.

Patroni süreci PGPASSWORD değişkenini devralırsa (tipik olarak birinin shell'inde export edilen bir superuser parolası), pg_rewind rewind_user olarak bağlanır ama yanlış kimlik bilgisini gönderir. Kimlik doğrulama başarısız olur, rewind atlanır ve düğüm bozuk kalır.

Temiz testler neden bunu yakalamıyor

Değişken yalnızca onu devralan Patroni sürecine zarar verir. Haftalar önce systemd tarafından düzgün başlatılan düğümler mutlu mutlu çoğaltmaya devam eder. Tehlikeli an, bir olaydan sonraki yeniden başlatmadır: bir operatör oturum açar, birkaç psql komutu çalıştırmak için PGPASSWORD'ü export eder ve Patroni'yi aynı shell'den başlatır, ya da bir kurtarma betiği bunu onun yerine yapar. pg_rewind'ı çalıştırması gereken süreci işte o süreçtir ve yanlış parolayı taşır.

Sorun oradan büyür. Patroni çoğaltmayı primary_conninfo içine bir parola gömmek yerine aynı passfile'a yönlendirir; bu yüzden o ortamla çalışan bir düğüm, elle yeniden inşa edildikten sonra bile leader'dan akış yapamaz. Yazar, laboratuvarlarında değişken yeniden başlatma yolunda bulunana kadar planlı her switchover'ın geçtiğini, her crash testinin ise başarısız olduğunu bildiriyor.

Yazı, değişkenin sızdığı dört yolu listeliyor: PGPASSWORD'ün export edildiği bir shell'den manuel nohup başlatmaları, set -a ile bir ortam dosyasını source eden deploy betikleri, diğer araçlarla paylaşılan Environment= veya EnvironmentFile= girdileri olan systemd unit'leri ve kolaylık olsun diye PGPASSWORD atan container imajları.

Kontrol edin ve düzeltin

Onu saniyelik kontrol, her düğümde çalışan Patroni sürecinin ortamını, /proc altındaki süreç girdisinden incelemek ve PG ve PATRONI_ önekli değişkenlere göre filtrelemektir. Herhangi bir PGPASSWORD, PGUSER, PGHOST veya PGSERVICE satırı bir sorundur. Beklenmeyen PATRONI_ satırları da öyle: Patroni her PATRONI_ önekli değişkeni yapılandırma olarak okur ve bunlar patroni.yml'yi geçersiz kılar. Yazar, bir betiğin ayarladığı PATRONI_LOG_DIR'ın logları beklenmedik bir yere gönderdiği ilgili bir vakayla karşılaştı.

Düzeltme, Patroni'yi yalnızca temiz ve açık bir ortamla systemd üzerinden çalıştırmaktır: unit içinde PATH'i tanımlayın, Environment= veya EnvironmentFile= satırlarından PGPASSWORD'ü kaldırın, sonra daemon-reload yapın ve Patroni'yi yeniden başlatın. Patroni yeniden başlarken PostgreSQL çalışmaya devam eder. Takılan düğümde Patroni'yi yeniden başlatmak genellikle yeterlidir, çünkü doğru parolayla pg_rewind'ı yeniden dener. İhtiyaç duyduğu WAL çoktan geri dönüştürüldüyse, düğümü patronictl reinit ile yeniden inşa edin.

Düzeltildiğini kanıtlamak

Bir switchover burada hiçbir şey kanıtlamaz; yalnızca bir çöküş kanıtlar. Yazarın tatbikatı, leader'ın Patroni ve PostgreSQL süreçlerini yazmalar devam ederken SIGKILL ile öldürür, yeni bir leader'ı bekler, eski düğümü yeniden başlatır ve streaming replica olarak yeniden katıldığını doğrular. Düzeltmeden sonra, laboratuvarlarındaki çöken leader'lar tutarlı biçimde yaklaşık 34 saniyede yeniden katıldı. Yazı, yazarının ticari HA kitiyle bitiyor; onun systemd unit'leri, önceden uyarıları ve yapılandırma üreticisi bu tuzakları önlemek için tasarlanmıştır.

Neden önemli

Failover araçları, başladıkları ortam kadar güvenilirdir. Tek bir devralınan ortam değişkeni Patroni'nin temel kurtarma yolunu sessizce etkisiz hale getirebilir ve tam en çok zarar vereceği anda ortaya çıkar: gerçek bir olay sırasında, bir insan müdahale ettiğinde. Dersler Patroni'nin ötesine genellenir: süreç ortamlarını PG* ve PATRONI_* değişkenleri açısından denetleyin, manuel yeniden başlatmalar yerine temiz systemd unit'lerini tercih edin ve failover'ı zarif switchover'lar yerine sert çöküşlerle doğrulayın. Belirli süreler ve düzeltmeler Patroni 4.1 ve PostgreSQL 16 üzerinde tek bir laboratuvarın testlerinden gelir.

  • #postgresql
  • #patroni
  • #high-availability
  • #devops
  • #databases