Ten wyjątek jest generowany przez serwer PostgreSQL 8.3.7 do mojej aplikacji. Czy ktoś wie, co oznacza ten błąd i co mogę z tym zrobić?
ERROR: cached plan must not change result type
STATEMENT: select code,is_deprecated from country where code=$1
Ten wyjątek jest generowany przez serwer PostgreSQL 8.3.7 do mojej aplikacji. Czy ktoś wie, co oznacza ten błąd i co mogę z tym zrobić?
ERROR: cached plan must not change result type
STATEMENT: select code,is_deprecated from country where code=$1
Odpowiedzi:
Dowiedziałem się, co powoduje ten błąd.
Moja aplikacja otworzyła połączenie z bazą danych i przygotowała instrukcję SELECT do wykonania.
W międzyczasie inny skrypt modyfikował tabelę bazy danych, zmieniając typ danych jednej z kolumn zwracanych w powyższej instrukcji SELECT.
Rozwiązałem ten problem, ponownie uruchamiając aplikację po zmodyfikowaniu tabeli bazy danych. Spowoduje to zresetowanie połączenia z bazą danych, umożliwiając wykonanie przygotowanej instrukcji bez błędów.
org.postgresql.util.PSQLException: ERROR: cached plan must not change result type
. Wszystkie testy działają jak urok, ale tylko Repository.findById()
. Nie zmieniam schematu w moich testach, ale używam @FlywayTest
do przygotowania testowej bazy danych init dla każdego testu. Jeśli usunę @FlywayTest
adnotację, działa dobrze.
Dodaję tę odpowiedź dla każdego, kto tu ląduje, szukając w Google ERROR: cached plan must not change result type
podczas próby rozwiązania problemu w kontekście aplikacji Java / JDBC.
Udało mi się niezawodnie odtworzyć błąd, uruchamiając aktualizacje schematu (tj. Instrukcje DDL), gdy działała moja aplikacja zaplecza, która korzystała z bazy danych. Jeśli aplikacja wysyłała zapytania do tabeli, która została zmieniona przez aktualizację schematu (tj. Aplikacja wykonywała zapytania przed i po aktualizacji w zmienionej tabeli) - sterownik postgres zwróciłby ten błąd, ponieważ najwyraźniej buforuje niektóre szczegóły schematu.
Możesz uniknąć problemu, konfigurując pgjdbc
sterownik z rozszerzeniem autosave=conservative
. Dzięki tej opcji sterownik będzie mógł opróżnić wszystkie szczegóły, które przechowuje w pamięci podręcznej, i nie powinieneś być zmuszony do odbijania serwera, opróżniania puli połączeń lub jakiegokolwiek innego obejścia, które możesz wymyślić.
Reprodukowane na Postgres 9.6 (AWS RDS) i moje wstępne testy wydają się wskazywać, że problem został całkowicie rozwiązany dzięki tej opcji.
Dokumentacja: https://jdbc.postgresql.org/documentation/head/connect.html#connection-parameters
Więcej szczegółów i historię problemu można znaleźć w pgjdbc
numerze 451 na Githubie .
Użytkownicy JRuby ActiveRecords widzą to: https://github.com/jruby/activerecord-jdbc-adapter/blob/master/lib/arjdbc/postgresql/connection_methods.rb#L60
Uwaga dotycząca wydajności:
Zgodnie z zgłoszonymi problemami z wydajnością w powyższym linku - przed ślepym włączeniem tej aplikacji należy przeprowadzić testy wydajności / obciążenia / nasiąknięcia.
Podczas testowania wydajności mojej własnej aplikacji działającej na wystąpieniu AWS RDS Postgres 10
, włączenie tego conservative
ustawienia powoduje dodatkowe zużycie procesora na serwerze bazy danych. Nie było to jednak dużo, mogłem nawet zobaczyć, jak autosave
funkcjonalność pojawia się jako użycie mierzalnej ilości procesora po dostrojeniu każdego zapytania, z którego korzystał mój test obciążenia i zacząłem mocno przesuwać test obciążenia.
Dla nas stanęliśmy przed podobnym problemem. Nasza aplikacja działa na wielu schematach. Za każdym razem, gdy robiliśmy zmiany schematu, ten problem zaczął się pojawiać.
Ustawienie parametru readyThreshold = 0 w parametrze JDBC wyłącza buforowanie instrukcji na poziomie bazy danych. To rozwiązało to za nas.