PostgreSQL HATASI: kurtarma çakışması nedeniyle bildirimi iptal etme


139

Bekleme modunda bir PostgreSQL db bir sorgu çalıştırırken aşağıdaki hatayı alıyorum. Hataya neden olan sorgu 1 ay boyunca iyi çalışır, ancak 1 aydan uzun bir süre sorguladığınızda bir hata oluşur.

ERROR: canceling statement due to conflict with recovery
Detail: User query might have needed to see row versions that must be removed

Nasıl çözüleceğine dair herhangi bir öneriniz var mı? Teşekkürler


O da çözüm vardır bu hatayı söz AWS doc bulabilirsiniz aws.amazon.com/blogs/database/...
arunjos007

Yanıtlar:


89

Otomatik bekleme sunucusunda sorgular çalıştırmak biraz zor - başarısız olabilir, çünkü sorgulama sırasında bazı gerekli satırlar birincil olarak güncellenebilir veya silinebilir. Birincil, bir sorgunun ikincilde başlatıldığını bilmediğinden, satırlarının eski sürümlerini temizleyebileceğini (vakumlayabileceğini) düşünür. Ardından ikincil bu temizlemeyi yeniden yürütmeli ve bu satırları kullanabilen tüm sorguları zorla iptal etmelidir.

Daha uzun sorgular daha sık iptal edilir.

Kukla bir sorgu yapan ve daha sonra ikincil üzerinde gerçek bir sorgu çalıştırılırken boşta duran bir tekrarlanabilir okuma işlemi başlatarak bu sorunu çözebilirsiniz. Onun varlığı, birincil olarak eski sıra versiyonlarının vakumlanmasını önleyecektir.

Bu konu ve diğer geçici çözümler hakkında daha fazla bilgi , Belgedeki Etkin Beklemede - Sorgu Çakışmalarını İşleme bölümünde açıklanmaktadır .


10
PostgreSQL 9.1+ kullanıcıları için: pratik bir çözüm için aşağıdaki eradman'ın cevabına bakınız.
Zoltán

3
PostgreSQL 9.1+ kullanıcılarına: max-malysh'in cevabı çok daha akılcı. Riskleri anlamadığınız sürece eradman önerisini yapmayın.
Davos

91

Dokunmaya gerek yok hot_standby_feedback. Diğerlerinin de belirttiği gibi, onustayı şişirebilir. Bir köle üzerinde işlemin açıldığını ve kapatılmadığını hayal edin.

Bunun yerine, max_standby_archive_delayve max_standby_streaming_delayaklı başında bazı değerlere ayarlayın:

# /etc/postgresql/10/main/postgresql.conf on a slave
max_standby_archive_delay = 900s
max_standby_streaming_delay = 900s

Bu şekilde süresi 900 saniyeden az olan köle sorgulamaları iptal edilmez. İş yükünüz daha uzun sorgu gerektiriyorsa, bu seçenekleri daha yüksek bir değere ayarlayın.


1
Sonunda kullandığımız çözüm bu. Burada sunulan tüm seçenekler arasında en iyi uzlaşma gibi görünüyor.
mohit6up

2
Bu en iyi cevap. Belgelere göre bunların birikimli olduğuna dikkat edin; çoğaltma üzerinde çoğaltma tutan birden çok sorgu varsa o zaman 899 almak olabilir sonra başka bir 2 saniye sorgu iptal edilir. Kodunuzda bazı üstel geri çekimler uygulamak en iyisidir. Ayrıca, çoğaltma akışı sırasında akış gecikmesi etkindir. Çoğaltma akışa devam edemezse, arşivden çoğaltmaya geçecektir. Arşivden çoğaltıyorsanız, muhtemelen onu yakalamasına izin vermelisiniz max_standby_archive_delay, diğerinden daha küçük olması gerekebilir.
Davos

2
Bu hala en iyi çözüm. Redshift'te bunu parametre grubu ayarları aracılığıyla ayarlayabileceğinizi unutmayın, sadece olması gerektiği gibi ms, yani 900s = 16 dakika = 900000ms.
NullDev


Bekleme amacının örneğin raporlama amaçlı olması ve yük devretme işlemine hazır olması gereken sıcak bir bekleme olmaması koşuluyla, bu kesinlikle en iyi yanıttır.
soupdog

77

Master üzerinde boşta işlemlere gerek yoktur. Postgresql-9.1'de bu sorunu çözmenin en doğrudan yolu

hot_standby_feedback = on

Bu, ustayı uzun süren sorgular hakkında bilgilendirecektir. Gönderen docs :

İlk seçenek, VACUUM'un son zamanlarda ölü olan satırları kaldırmasını ve böylece temizleme çakışmalarının oluşmasını önleyen hot_standby_feedback parametresini ayarlamaktır.

Bu neden varsayılan değil? Bu parametre ilk uygulamadan sonra eklenmiştir ve bekleme modunun bir master'ı etkilemesinin tek yolu budur.


11
Bu parametre bekleme modunda ayarlanmalıdır.
Steve Kehlet

3
Bu durumda usta için bazı dezavantajlar vardır Sıcak Bekleme-Geribildirim
Evgeny Liskovets

50

Belirtildiği gibi burada yaklaşık hot_standby_feedback = on:

Bunun dezavantajı, beklemenin bazı insanlar için de şaşırtıcı olabilecek efendiyi şişirebilmesidir.

Ve burada :

Hangi max_standby_streaming_delay ayarı ile? Ben varsayılan olarak -1 varsayılan hot_standby_feedback daha varsayılan. Bu şekilde bekleme modunda yaptığınız işlemler yalnızca bekleme modunu etkiler


Ben de ekledim

max_standby_streaming_delay = -1

Ve pg_dumpbizim için daha fazla hata yok , ne de usta şişkinlik :)

AWS RDS örneği için http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.html adresini ziyaret edin


1
@lennard, bu benim için çalıştı. Bu yapılandırmayı slave'in postgresql.conf dosyasına ekledim, sonra slave'i yeniden başlattım.
Ardee Aram

13
Elbette, bu şekilde sınırsız çoğaltma gecikmesini elde edebilirsiniz. Ve çoğaltmayı master'a bağlamak için bir çoğaltma yuvası kullanıyorsanız, bu, master'da aşırı xlog tutmaya neden olabilir, bu yüzden gerçekten sadece WAL arşivleme kullanıyorsanız uygulanabilir.
Craig Ringer

7
Bunu AWS RDS'de nasıl ayarlayabilirim?
Kris MP

1
@KrisMP Kullanım psql'in
Yehonatan


13

Uzun süre çalışmakta olan bir sorgu çalışırken çalışırken bekleme ikincil sunucusundaki tablo verileri değiştirilir. Tablo verilerinin değiştirilmediğinden emin olmak için bir çözüm (PostgreSQL 9.1+) çoğaltmayı askıya almak ve sorgudan sonra devam etmektir:

select pg_xlog_replay_pause(); -- suspend
select * from foo; -- your query
select pg_xlog_replay_resume(); --resume

1
Bu süper kullanıcı hakları gerektirir. Bu yüzden bazı durumlarda bir çözüm olmayabilir.
Joao Baltazar

1
PostgreSQL 10 yılında xlogile değiştirildi walaramak istediğiniz böylece, pg_wal_replay_pause()ve pg_wal_replay_resume().
womble

3

Cevap için çok geç olabilir, ancak üretim konusunda da aynı sorunla karşı karşıyayız. Daha önce sadece bir RDS var ve uygulama tarafında kullanıcı sayısı arttıkça, bunun için Okuma Çoğaltması eklemeye karar verdik. Okuma çoğaltması sahnelemede düzgün çalışır, ancak üretime geçtikten sonra aynı hatayı almaya başlarız.

Bu nedenle , Postgres özelliklerinde hot_standby_feedback özelliğini etkinleştirerek bunu çözüyoruz . Aşağıdaki bağlantıya değindik

https://aws.amazon.com/blogs/database/best-practices-for-amazon-rds-postgresql-replication/

Umarım yardımcı olur.


2

Yukarıda @ max-malysh'ın mükemmel cevabına bazı güncellenmiş bilgiler ve referanslar ekleyeceğim.

Kısacası, efendide bir şey yaparsanız, köle üzerinde çoğaltılması gerekir. Postgres bunun için WAL kayıtlarını kullanır, bu kayıtlar master üzerinde her kaydedilmiş eylemden sonra slave'e gönderilir. Ardından köle eylemi yürütür ve ikisi yeniden senkronize olur. Birkaç senaryodan birinde, bir WAL eyleminde efendiden gelenlerle köle üzerinde çatışma yaşayabilirsiniz. Çoğunda, köle üzerinde WAL eyleminin değiştirmek istediği şeyle çelişen bir işlem var. Bu durumda, iki seçeneğiniz vardır:

  1. WAL eyleminin uygulanmasını biraz geciktirerek, slave'in çakışan işlemini bitirmesine izin verin, ardından eylemi uygulayın.
  2. Slave'deki çakışan sorguyu iptal edin.

# 1 ve iki değerle ilgileniyoruz:

  • max_standby_archive_delay - bu, veriler geçerli veri olmayan bir WAL arşivinden okunurken, master ve slave arasındaki uzun bir bağlantı kesilmesinden sonra kullanılan gecikmedir.
  • max_standby_streaming_delay - akış çoğaltması yoluyla WAL girdileri alındığında sorguları iptal etmek için kullanılan gecikme.

Genel olarak, sunucunuz yüksek kullanılabilirlikli çoğaltma amaçlıysa, bu sayıları kısa tutmak istersiniz. Bunun için varsayılan ayar 30000(milisaniye belirtilmemişse milisaniye) yeterlidir. Bununla birlikte, çok uzun süren sorguları olabilen bir arşiv, raporlama veya okuma-çoğaltma gibi bir şey ayarlamak istiyorsanız, iptal edilen sorguları önlemek için bunu daha yüksek bir şeye ayarlamak istersiniz. Yukarıda önerilen 900sayar iyi bir başlangıç ​​noktası gibi görünür. -1İyi bir fikir olarak sonsuz bir değer belirleme konusunda resmi belgelere katılmıyorum - bazı hata kodlarını maskeleyebilir ve birçok soruna neden olabilir.

Uzun süren sorgular ve bu değerlerin daha yüksek ayarlanmasıyla ilgili bir uyarı, WAL eyleminin gecikmesine neden olan uzun süredir devam eden soruna paralel olarak slave üzerinde çalışan diğer sorguların, uzun sorgu tamamlanana kadar eski verileri görmesidir. Geliştiricilerin bunu anlamaları ve aynı anda çalıştırılmaması gereken sorguları serileştirmeleri gerekecektir.

Nasıl max_standby_archive_delayve nasıl max_standby_streaming_delayçalıştığının ve nedeninin tam açıklaması için buraya gidin .


1

Benzer şekilde, her ikisi de yukarıda @ max-malysh'ın mükemmel cevabının @ Artif3x detaylandırılması için 2. bir uyarı.

Kaptandan yapılan işlemlerin herhangi bir gecikmeli uygulamasıyla, takipçi (ler) verilerin daha eski ve eski bir görünümüne sahip olacaktır. Bu nedenle, max_standby_archive_delay ve max_standby_streaming_delay öğelerini ayarlayarak takipçideki sorgunun tamamlanması için zaman sağlarken, her iki uyarıyı da aklınızda bulundurun:

Yedekleme için takipçinin değeri, barındırma sorgularıyla çok fazla çelişiyorsa, bir çözüm, her biri biri veya diğeri için optimize edilmiş birden fazla takipçi olacaktır.

Ayrıca, bir satırdaki birkaç sorgunun wal girişlerinin uygulanmasının gecikmesine neden olabileceğini unutmayın. Bu nedenle, yeni değerleri seçerken, yalnızca tek bir sorgunun zamanı değil, çakışan bir sorgu başladığında başlayan ve wal girişi sonunda uygulandığında biten hareketli bir pencere.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.