Postgres: "HATA: önbelleğe alınan plan sonuç türünü değiştirmemelidir"


115

Bu istisna, PostgreSQL 8.3.7 sunucusu tarafından uygulamama atılıyor. Bu hatanın ne anlama geldiğini ve bu konuda ne yapabileceğimi bilen var mı?

ERROR:  cached plan must not change result type
STATEMENT:  select code,is_deprecated from country where code=$1

Lütfen PostreSQL'in tam sürümünü paylaşır mısınız? 8.3.X?

Yanıtlar:


190

Bu hataya neyin sebep olduğunu buldum.

Uygulamam bir veritabanı bağlantısı açtı ve yürütme için bir SELECT ifadesi hazırladı.

Bu arada, başka bir komut dosyası veritabanı tablosunu değiştiriyor, yukarıdaki SELECT deyiminde döndürülen sütunlardan birinin veri türünü değiştiriyordu.

Veritabanı tablosu değiştirildikten sonra uygulamayı yeniden başlatarak bunu çözdüm. Bu, veritabanı bağlantısını sıfırlayarak hazırlanan ifadenin hatasız yürütülmesine izin verir.


4
Bunu PostgreSQL 9.0.4'te Ruby on Rails 3.1-pre5 ile aldım. Görünüşe göre bunun ActiveRecord tarafından otomatik olarak halledilmesi gerekiyor, değil mi?
docwhat

3
Evet, umarım ActiveRecord sonunda bununla ilgilenir. Yeniden başlatmaktan kaçınmak istiyorsanız, MyModel.reset_column_information'ı çağırmanın kısa vadede sorunları çözeceğine inanıyorum.
Grant Hutchins

1
Neyin yanlış gittiğini anlamak için bir saatimi boşa harcadım. Cevabınız beni kurtardı!
Sri Harsha Kappala

3
Herhangi bir çözümün tüm uygulamayı veya postgres sunucusunu yeniden başlatmayı gerektirmediğini biliyor musunuz? Hata oluştuğunda önbelleğe alınmış planı manuel olarak temizlemek için bir çözüm olabilir mi?
Jacek Gzel

1
Spring + jpa uygulaması için JUnit testleri çalıştırırken aynı sorunu Postgres 10'da yaşadım. Özel durum iletisi: org.postgresql.util.PSQLException: ERROR: cached plan must not change result type. Ve tüm testler bir cazibe gibi çalışır, ancak yalnızca Repository.findById(). Testlerimde şemayı değiştirmiyorum, ancak @FlywayTesther test için bir test başlatma veritabanı hazırlamak için kullanıyorum . @FlywayTestEk açıklamayı kaldırırsam iyi çalışıyor.
Binakot

25

Bu cevabı ERROR: cached plan must not change result type, bir Java / JDBC uygulaması bağlamında sorunu çözmeye çalışırken googling yaparak buraya gelen herkes için ekliyorum .

DB'yi kullanan arka uç uygulamam çalışırken şema yükseltmelerini (yani DDL ifadeleri) çalıştırarak hatayı güvenilir bir şekilde yeniden oluşturabildim. Uygulama, şema yükseltmesiyle değiştirilen bir tabloyu sorguluyorsa (yani, uygulama, değiştirilen bir tabloda yükseltmeden önce ve sonra sorgular çalıştırıyorsa) - postgres sürücüsü bu hatayı döndürür çünkü görünüşe göre bazı şema ayrıntılarını önbelleğe alır.

pgjdbcSürücünüzü ile yapılandırarak sorunu önleyebilirsiniz autosave=conservative. Bu seçenekle, sürücü önbelleğe aldığı ayrıntıları temizleyebilir ve sunucunuzu geri döndürmeniz veya bağlantı havuzunuzu temizlemeniz veya bulduğunuz herhangi bir geçici çözümü bulmanız gerekmez.

Postgres 9.6'da (AWS RDS) yeniden oluşturuldu ve ilk testlerim, sorunun bu seçenekle tamamen çözüldüğünü gösteriyor.

Belgeler: https://jdbc.postgresql.org/documentation/head/connect.html#connection-parameters

pgjdbc Sorunla ilgili daha fazla ayrıntı ve tarihçe için Github 451 sayısına bakabilirsiniz .


JRuby ActiveRecords kullanıcıları bunu görür: https://github.com/jruby/activerecord-jdbc-adapter/blob/master/lib/arjdbc/postgresql/connection_methods.rb#L60


Performansla ilgili not:

Yukarıdaki bağlantıda bildirilen performans sorunlarına göre - bunu körü körüne açmadan önce uygulamanızda bazı performans / yükleme / ıslatma testleri yapmanız gerekir.

AWS RDS Postgres 10örneğinde çalışan kendi uygulamamda performans testi yaparken , conservativeayarın etkinleştirilmesi veritabanı sunucusunda fazladan CPU kullanımına neden oluyor. Yine de çok fazla değildi, autosaveyük testimin kullandığı her sorguyu ayarladıktan ve yük testini zorlamaya başladıktan sonra , işlevselliğin ölçülebilir miktarda CPU kullanıyormuş gibi göründüğünü bile görebiliyordum .


7
Neden bu varsayılan değil?
cdmckay

1
İlan edildiği gibi çalışır. Basit testlerim herhangi bir performans etkisi göstermedi.
Samuli Pahaoja

1
Ruby Postgres sürücüsü ile nasıl yapılandırılır?
Hrishi

@Hrishi Yorumunuz, orijinal sorunun aslında Java'yı belirtmediğini fark etmemi sağladı (çünkü bir Java bağlamında problemle uğraşırken buldum). Ruby bağlamında açıkça bir çözüm arayan tamamen yeni bir soru göndermek isteyebileceğinizi söyleyebilirim.
2019

@cdmckay Çünkü 9.4-ish zaman diliminde sürücüye eklenen yeni bir işlevsellikti. İhtiyacım olmayan yeni, kanıtlanmamış, performans düşürücü işlevselliği varsayılan olarak etkinleştirdiği için, pgjdbc'nin bazı yeni bir sürümü uygulamamı bozarsa çok mutsuz olurum. (Bununla birlikte, bu artık benim "her zaman yeni bir uygulama oluştururken bunu yap" kontrol listemde yeni bir giriştir).
2019

0

Bizim için benzer bir sorunla karşı karşıyaydık. Uygulamamız çoklu şema üzerinde çalışmaktadır. Ne zaman şema değişiklikleri yapsak, bu sorun oluşmaya başladı.

JDBC parametresi içinde preparThreshold = 0 parametresinin ayarlanması , veritabanı düzeyinde ifade önbelleğe almayı devre dışı bırakır. Bu bizim için çözdü.

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.